列表视图的单元格重用问题和自定义渲染器的视图单元格
Cell-reusing issue with list view and view cells with custom renderer
我正在尝试显示一个列表视图,其中包含使用自定义 iOS 渲染器渲染的单元格。滚动列表时,会出现令人讨厌的叠加层(如下所示)。我将其归结为以下代码行。
App
包含一个 ListView
,其 ItemsSource
设置为从 A 到 Z 的所有字符的虚拟列表。ItemTemplate
是使用自定义 ItemCell
定义如下。
public class App : Application
{
public App()
{
MainPage = new ContentPage {
Content = new ListView {
ItemsSource = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),
ItemTemplate = new DataTemplate(typeof(ItemCell)),
},
};
}
}
ItemCell
包含绑定到列表项的 Label
。
public class ItemCell: ViewCell
{
public ItemCell()
{
View = new Label();
View.SetBinding(Label.TextProperty, ".");
}
}
在 iOS 上 Label
使用以下 FixedLabelRenderer
呈现。它设置由包含 Element
的 Text
.
的 UILabel
表示的本机控件
public class FixedLabelRenderer : ViewRenderer<Label, UILabel>
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
SetNativeControl(new UILabel(RectangleF.Empty) { Text = Element.Text });
}
}
现在的问题是,显然,当重新使用一个单元格时,控件并没有被删除,而只是创建了一个新的控件。所以我得到了下面屏幕截图中显示的叠加层。
(左:滚动前,右:滚动后)
有趣的是,Xamarin.Forms 1.2.3 或 1.3.1 不会出现此问题,但 1.3.5 和 1.4.0 会出现此问题。
哦,我找到了解决办法on the Xamarin Forum:
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control == null)
SetNativeControl(new UILabel());
if (e.NewElement != null)
Control.Text = e.NewElement.Text;
}
所以基本上你需要确保只创建 一个 UILabel
然后再使用它。
我正在尝试显示一个列表视图,其中包含使用自定义 iOS 渲染器渲染的单元格。滚动列表时,会出现令人讨厌的叠加层(如下所示)。我将其归结为以下代码行。
App
包含一个 ListView
,其 ItemsSource
设置为从 A 到 Z 的所有字符的虚拟列表。ItemTemplate
是使用自定义 ItemCell
定义如下。
public class App : Application
{
public App()
{
MainPage = new ContentPage {
Content = new ListView {
ItemsSource = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),
ItemTemplate = new DataTemplate(typeof(ItemCell)),
},
};
}
}
ItemCell
包含绑定到列表项的 Label
。
public class ItemCell: ViewCell
{
public ItemCell()
{
View = new Label();
View.SetBinding(Label.TextProperty, ".");
}
}
在 iOS 上 Label
使用以下 FixedLabelRenderer
呈现。它设置由包含 Element
的 Text
.
UILabel
表示的本机控件
public class FixedLabelRenderer : ViewRenderer<Label, UILabel>
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
SetNativeControl(new UILabel(RectangleF.Empty) { Text = Element.Text });
}
}
现在的问题是,显然,当重新使用一个单元格时,控件并没有被删除,而只是创建了一个新的控件。所以我得到了下面屏幕截图中显示的叠加层。
有趣的是,Xamarin.Forms 1.2.3 或 1.3.1 不会出现此问题,但 1.3.5 和 1.4.0 会出现此问题。
哦,我找到了解决办法on the Xamarin Forum:
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control == null)
SetNativeControl(new UILabel());
if (e.NewElement != null)
Control.Text = e.NewElement.Text;
}
所以基本上你需要确保只创建 一个 UILabel
然后再使用它。