Android 的 ListView 重新使用已滚出 View 的行。 但是,在 C# 中处理行的 subview 上的事件时,这似乎是一个问题。
在 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<ImageView> (Resource.Id.pic);
img.Click += (sender, e) => {
Console.WriteLine(position);
};
上面设置事件处理程序的 Java 模式非常适合行重用,而下面添加事件处理程序的 C# 模式导致处理程序堆积在子进程上重用行的 View 。
下面的代码显示了我编写的自定义 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<ImageView> (Resource.Id.profilePic);
//if(profilePic.Clickable) { /** kill click handlers? **/ }
profilePic.Click += async (object sender, EventArgs e) => {
Bundle extras = new Bundle();
extras.PutString("id", UserList[position].id);
Intent intent = new Intent(userListContext, typeof(ProfileActivity));
intent.PutExtras(extras);
postListContext.StartActivity(intent);
};
return row;
}
问题是,当一行被重复使用时,profilePic
View 仍然附加了原始的“点击”处理程序。
有没有办法 (a) 消除 profilePic.Click
或 (b) 使用 Android 的 profilePic.SetOnClickListener
具有匿名函数的 Java 模式?
或者,是否有更好的模式可以让“点击”处理程序仍然可以访问 position
的正确值?
最佳答案
Or, is there a better pattern to use where the "click" handler can still access the proper value of position?
使用 setTag/getTag
方法在 ImageView
点击监听器的 Click 方法中获取被点击行的正确位置:
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);
......
};
关于c# - Monodroid - 处理重用 ListView 行的 subview 上的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28534257/