ArrayAdapter が設定された ListView があり、アダプターの各行には、クリック イベントを受け取って処理する必要がある 4 つのボタンが含まれています。通常、Android ではSetOnClickListener
セルを作成するときに各ボタンを呼び出しますが、Mono では代わりにイベントのイベント ハンドラーを設定できますClick
。ただし、イベント ハンドラーを設定する場所に応じて 2 つの問題のいずれかに遭遇するため、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));
}
ここでは、イベント ハンドラーはボタンごとに 1 回しか設定されませんが (良いことです!)、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));
このメソッドは正しい に対してクリック イベントを発生させますがposition
、行がリサイクルされるたびに新しいイベント ハンドラーを設定します。これにより、多数の行に対して同時にクリック イベントが発生します。このメソッドの回避策は、イベント ハンドラーへの参照を保持し、それらを 内GetView
で再度設定する前に削除することですが、これは非常に洗練されていないようです。
Monodroid の ListView アイテム内でクリック イベントを処理するためのより良い方法はありますか?