2012-11-08 156 views
0

我为列表视图使用自定义列表适配器。我在列表视图中定义了一个按钮,点击事件起作用,但问题是一旦列表滚动,它就会用同一个按钮绑定多个视图。因此,点击按钮时,与每个关联视图关联的事件被触发。按钮点击绑定到自定义列表视图中的多个视图

我该如何处理?

+1

显示您的代码。没有代码它不可能解决:) –

+0

view =(convertView ?? context.LayoutInflater.Inflate(Resource.Layout.HotelCustomListItem,parent,false))作为LinearLayout; –

+0

这基本上是在这里完成的。我在上述布局中定义了一个按钮。当列表滚动时,会创建新视图,但与每个视图关联的控件似乎是相同的。 –

回答

0

我想你会误解这个列表是如何工作的 - 尤其是如何使用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; 
} 

那反正是我的猜测:)

0

斯图尔特是完全正确的 - 问题是,意见中的ListView重复使用(以避免产生不同的对象),和列表的不同部分是可见的,因为你的新位置可以得到任何不再使用的视图。所以你的代码应该正确处理。 我想补充一点,monodroid中的Java对象的垃圾收集效果不好。根据我的经验,创建大量来自Java.Lang.Object的对象会使应用程序崩溃。所以:

  1. 为每个新行创建新的视图很快会使应用程序崩溃,因此您必须尽可能重用convertView。

  2. 标签有类型Java.Lang.Object,所以WrappedPosition应该从Java对象派生。这意味着,不是每次都创建新的实例,而应该重用相同的实例。

  3. 如果您将点击处理程序移动到单独的方法,您可以在订阅之前取消订阅,因此您不需要任何逻辑“如果视图为空”。

如果您觉得它有用,我可以在这里发布解释它如何工作的代码示例。 Dodn't最初发布它,因为它是相当大的:)

相关问题