【发布时间】:2013-04-25 13:11:11
【问题描述】:
我有一个设置了 ArrayAdapter 的 ListView,并且适配器中的每一行都包含四个需要接收和处理点击事件的按钮。通常在 Android 中,当我创建单元格时,我会在每个按钮上调用 SetOnClickListener,但 Mono 提供了为 Click 事件设置事件处理程序的能力。不过,在 Mono 中似乎有些奇怪,因为我遇到了两个问题之一,具体取决于我设置事件处理程序的位置。
ArrayAdapter GetView 示例一:
View tweetCell = convertView;
if (tweetCell == null) {
tweetCell = ((LayoutInflater)Context.GetSystemService (Context.LayoutInflaterService)).Inflate (Resource.Layout.TweetCell, null);
tweetCell.FindViewById (Resource.Id.btn_moveTweet).Click += (object sender, EventArgs e) => MoveTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_unfavoriteTweet).Click += (object sender, EventArgs e) => UnfavoriteTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_hideTweet).Click += (object sender, EventArgs e) => HideTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_shareTweet).Click += (object sender, EventArgs e) => ShareTweet (GetItem(position));
}
在这里,我的事件处理程序每个按钮只设置一次(很好!),但position 的值大部分时间都是错误的。我想知道从 Mono 到 Android 代码的转换是否导致 GetItem(position) 每次都为 position 使用相同的值(position 在首次创建单元格时设置的值)。此代码在普通 Android 中完全可以正常工作。
ArrayAdapter GetView 示例 2:
View tweetCell = convertView;
if (tweetCell == null) {
tweetCell = ((LayoutInflater)Context.GetSystemService (Context.LayoutInflaterService)).Inflate (Resource.Layout.TweetCell, null);
}
tweetCell.FindViewById (Resource.Id.btn_moveTweet).Click += (object sender, EventArgs e) => MoveTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_unfavoriteTweet).Click += (object sender, EventArgs e) => UnfavoriteTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_hideTweet).Click += (object sender, EventArgs e) => HideTweet (GetItem(position));
tweetCell.FindViewById (Resource.Id.btn_shareTweet).Click += (object sender, EventArgs e) => ShareTweet (GetItem(position));
此方法确实会为正确的position 触发 click 事件,但它会在每次回收该行时设置一个新的事件处理程序。这会同时导致很多行的点击事件。此方法的解决方法似乎是保留对事件处理程序的引用并在将它们再次设置到 GetView 之前将其删除,但这似乎非常不雅。
有没有更好的方法来处理 Monodroid 中 ListView 项内的点击事件?
【问题讨论】:
-
我遇到了同样的问题。我解决它的方法是使用 ViewHolder 模式。您始终可以将 convertView 的位置推到标签中,然后在单击事件处理程序中将其拉出。
标签: android android-listview mono xamarin.android xamarin