Android的ListView重用已滚出视图的行.
但是,当在C#中处理行的子视图上的事件时,这似乎是一个问题.
在Java中添加事件处理程序的一种可接受的方法是显式设置一个像这样的处理程序:
ImageView img = (ImageView) row.findViewById(R.id.pic);
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
System.out.println(position);
}
});
Xamarin网站上的文档鼓励开发人员使用C#的add事件监听器模式,这种模式对重用行不起作用:
ImageView img = row.FindViewById
上面设置事件处理程序的Java模式非常适合于行重用,而在其下面添加事件处理程序的C#模式会导致处理程序堆积在重用行的子视图上.
下面的代码显示了我编写的自定义BaseAdapter中的GetView方法.
public override Android.Views.View GetView (int position,View convertView,ViewGroup parent)
{
View row = convertView;
//TODO: solve event listener bug. (reused rows retain events).
if (row == null) {
row = LayoutInflater.From (userListContext)
.Inflate (Resource.Layout.UserListUser,null,false);
}
ImageView profilePic = row.FindViewById
问题是,当重用行时,profilePic视图仍然附加了原始的“click”处理程序.
有没有办法(a)消灭profilePic.Click或(b)使用Android的profilePic.SetOnClickListener Java模式与匿名函数?
或者,有没有更好的模式使用“点击”处理程序仍然可以访问正确的位置值?
最佳答案
Or,is there a better pattern to use where the “click” handler can
still access the proper value of position?
使用setTag / getTag方法获取Clicked行内部的正确位置ClickView单击侦听器的方法:
profilePic.SetTag(Resource.Id.profilePic,position);
profilePic.Click += async (object sender,EventArgs e) => {
int clickedPos = (int)(((Button)sender).GetTag (Resource.Id.profilePic));
Bundle extras = new Bundle();
extras.PutString("id",UserList[clickedPos].id);
......
};