Tôi có một ListView với một bộ ArrayAdapter vào nó, và mỗi hàng trong bộ điều hợp chứa bốn nút cần nhận và xử lý các sự kiện bấm. Thông thường trong Android, tôi sẽ gọi SetOnClickListener
trên mỗi nút khi tôi tạo ô, nhưng Mono cung cấp khả năng đặt trình xử lý sự kiện cho sự kiện Click
thay thế. Có vẻ như có một số điều kì lạ trong Mono, bởi vì tôi gặp phải một trong hai vấn đề phụ thuộc vào nơi tôi đặt trình xử lý sự kiện.Monodroid - Xử lý Nhấp vào các sự kiện bên trong hàng ListAdapter
ArrayAdapter GetView Ví dụ 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));
}
Ở đây, xử lý sự kiện của tôi chỉ được thiết lập một lần cho mỗi nút (tốt!), Nhưng giá trị position
là sai hầu hết thời gian. Tôi tự hỏi liệu chuyển đổi từ mã Mono sang Android có đang gây ra GetItem(position)
để sử dụng cùng một giá trị cho position
mỗi lần (giá trị position
được đặt thành khi ô được tạo lần đầu). Mã này sẽ hoạt động hoàn toàn bình thường trên Android.
ArrayAdapter GetView Ví dụ 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));
Phương pháp này không gây ra các sự kiện nhấp chuột để bị sa thải cho đúng position
, nhưng nó đặt một xử lý sự kiện mới mỗi khi hàng được tái chế. Điều này gây ra các sự kiện nhấp cho nhiều hàng cùng một lúc. Một cách giải quyết cho phương pháp này có vẻ là để giữ cho các tham chiếu đến các trình xử lý sự kiện và loại bỏ chúng trước khi đặt chúng lại bên trong GetView
, nhưng điều này có vẻ vô cùng không thích hợp.
Có phương pháp nào tốt hơn để xử lý các sự kiện nhấp trong các mục ListView trong Monodroid không?
Tôi chạy vào cùng một vấn đề. Cách tôi giải quyết nó đã sử dụng mẫu ViewHolder. Bạn luôn có thể đẩy vị trí trong Thẻ cho convertView và kéo nó ra trong trình xử lý sự kiện nhấp chuột. – snowCrabs