【发布时间】:2015-04-16 12:58:39
【问题描述】:
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<ImageView> (Resource.Id.pic);
img.Click += (sender, e) => {
Console.WriteLine(position);
};
设置事件处理程序的 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<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 视图仍然附加了原始的“点击”处理程序。
有没有办法 (a) 清除 profilePic.Click 或 (b) 使用带有匿名函数的 Android 的 profilePic.SetOnClickListener Java 模式?
或者,在“点击”处理程序仍然可以访问 position 的正确值的情况下,是否有更好的模式可以使用?
【问题讨论】:
标签: c# android mono xamarin xamarin.android