我有一个设置了 ArrayAdapter 的 ListView,并且适配器中的每一行都包含四个需要接收和处理单击事件的按钮。通常在 Android 中,我会SetOnClickListener
在创建单元格时调用每个按钮,但 Mono 提供了为事件设置事件处理程序的能力Click
。不过,在 Mono 中似乎有些奇怪,因为我遇到了两个问题之一,具体取决于我设置事件处理程序的位置。
ArrayAdapter GetView 示例 1:
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)
使用相同的值(首次创建单元格时设置的值)。此代码在普通 Android 中完全可以正常工作。position
position
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));
此方法确实会为正确的 触发 click 事件position
,但它会在每次回收该行时设置一个新的事件处理程序。这会同时导致很多行的点击事件。此方法的解决方法似乎是保留对事件处理程序的引用并在再次将它们设置在内部之前将其删除GetView
,但这似乎非常不雅。
有没有更好的方法来处理 Monodroid 中 ListView 项目内的点击事件?