我为列表视图使用自定义列表适配器。我在列表视图中定义了一个按钮,点击事件起作用,但问题是一旦列表滚动,它就会用同一个按钮绑定多个视图。因此,点击按钮时,与每个关联视图关联的事件被触发。按钮点击绑定到自定义列表视图中的多个视图
我该如何处理?
我为列表视图使用自定义列表适配器。我在列表视图中定义了一个按钮,点击事件起作用,但问题是一旦列表滚动,它就会用同一个按钮绑定多个视图。因此,点击按钮时,与每个关联视图关联的事件被触发。按钮点击绑定到自定义列表视图中的多个视图
我该如何处理?
我想你会误解这个列表是如何工作的 - 尤其是如何使用convertView。
列表视图中的Android虚拟化的用户界面 - 就像列表框做WP和就像UITableViews做的iOS
这意味着,如果底层的列表中有1000个项目,但屏幕只有房间10个项目,那么列表只会创建10个“容器”来显示列表项目,并将使用这些容器来显示当时正在查看的内容。
它这样做的方式是通过适配器 - 特别是通过GetView回调 - 它将convertView作为其参数之一。
如果您选择在GetView实现来创建一个新的观点,那么你可以订阅回调的新事件...
相反,如果你选择使用convertView在GetView实现,那么你应该不要在回调中订阅新事件 - 不要先退订旧事件。
例如我猜你的代码确实是这样的伪目前:
public View GetView(int pos, View convertView)
{
TextView toShow = convertView as TextView;
if (toShow == null)
{
toShow = new TextView();
}
toShow.Text = "Item at position " + i;
toShow.Click += (s,e) => {
// do something
};
return toShow;
}
与代码的问题是,你将认购过于频繁点击......你需要的东西,如来解决它:
public View GetView(int pos, View convertView)
{
TextView toShow = convertView as TextView;
if (toShow == null)
{
toShow = new TextView();
toShow.Click += (s,e) => {
// do something with the position embedded in toShow.Tag
};
}
toShow.Text = "Item at position " + i;
toShow.Tag = new WrappedPosition(i);
return toShow;
}
那反正是我的猜测:)
斯图尔特是完全正确的 - 问题是,意见中的ListView重复使用(以避免产生不同的对象),和列表的不同部分是可见的,因为你的新位置可以得到任何不再使用的视图。所以你的代码应该正确处理。 我想补充一点,monodroid中的Java对象的垃圾收集效果不好。根据我的经验,创建大量来自Java.Lang.Object的对象会使应用程序崩溃。所以:
为每个新行创建新的视图很快会使应用程序崩溃,因此您必须尽可能重用convertView。
标签有类型Java.Lang.Object,所以WrappedPosition应该从Java对象派生。这意味着,不是每次都创建新的实例,而应该重用相同的实例。
如果您将点击处理程序移动到单独的方法,您可以在订阅之前取消订阅,因此您不需要任何逻辑“如果视图为空”。
如果您觉得它有用,我可以在这里发布解释它如何工作的代码示例。 Dodn't最初发布它,因为它是相当大的:)
显示您的代码。没有代码它不可能解决:) –
view =(convertView ?? context.LayoutInflater.Inflate(Resource.Layout.HotelCustomListItem,parent,false))作为LinearLayout; –
这基本上是在这里完成的。我在上述布局中定义了一个按钮。当列表滚动时,会创建新视图,但与每个视图关联的控件似乎是相同的。 –