Tôi đã đưa ra một giải pháp chung và có thể tái sử dụng. Thay vì mở rộng bộ điều hợp danh sách cụ thể và sửa đổi phương thức getView()
, tôi đã tạo một lớp mới triển khai giao diện ListAdapter
chuyển tiếp một cách mù quáng gần như mọi thứ sang một số khác ListAdapter
ngoại trừ getView()
. Nó trông giống như thế này:
public class SubClickableListAdapter implements ListAdapter {
public static interface OnSubItemClickListener {
public void onSubItemClick(View subView, int position);
}
private ListAdapter other;
private SparseArray<OnSubItemClickListener> onClickListeners;
public SubClickableListAdapter(ListAdapter other) {
this.other = other;
onClickListeners = new SparseArray<OnSubItemClickListener>();
}
public void setOnClickListener(int id, OnSubItemClickListener listener) {
onClickListeners.put(id, listener);
}
public void removeOnClickListener(int id) {
onClickListeners.remove(id);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = other.getView(position, convertView, parent);
for(int i = 0; i < onClickListeners.size(); i++) {
View subView = view.findViewById(onClickListeners.keyAt(i));
if (subView != null) {
final OnSubItemClickListener listener = onClickListeners.valueAt(i);
if (listener != null) {
subView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
listener.onSubItemClick(v, position);
}
});
}
}
}
return view;
}
// other implemented methods
}
Các phương pháp thực hiện khác chỉ đơn giản giống như một sau:
@Override
public Object getItem(int position) {
return other.getItem(position);
}
Để sử dụng nó, bạn chỉ cần khởi tạo nó cung cấp bất kỳ khác ListAdapter
(có thể là ArrayAdapter
hoặc SimpleCursorAdapter
hoặc bất cứ điều gì khác). Sau đó, hãy gọi setOnClickListener()
cho mỗi chế độ xem nơi bạn muốn nghe trên nhấp chuột, cung cấp id của nó trong thông số id
và trình nghe của bạn trong thông số listener
. Để lấy id hàng cho hàng đã được nhấp, hãy gọi phương thức getItemIdAtPosition(position)
của ListView của bạn (bạn phải theo cách khác, vì nó không được dùng làm tham số cho gọi lại của bạn, nhưng đó không phải là vấn đề lớn nhất các trường hợp).
Ưu điểm của giải pháp này là nó có thể được sử dụng với bất kỳ ListAdapter
nào. Vì vậy, nếu ứng dụng của bạn có một số ListView
s, mỗi ứng dụng sử dụng các chế độ xem cơ bản khác nhau hoặc thậm chí các bộ điều hợp khác nhau, bạn không phải tạo một lớp bộ điều hợp mới cho từng loại.
Sự cố với vấn đề này giống với tất cả các giải pháp khác: OnItemClick()
của ListView
sẽ không được gọi nếu bạn nhấp vào chế độ xem mà bạn đã đăng ký người nghe. Đối với các giao diện mà bạn không đăng ký người nghe, cuộc gọi lại này sẽ được gọi là mặc dù.Ví dụ: bạn có hoạt động cho mục danh sách chứa hai trường văn bản và nút và bạn đăng ký trình nghe cho nút, sau đó nhấp vào nút sẽ không gọi số OnItemClick()
của số ListView
, nhưng gọi lại của bạn . Nhấp vào bất kỳ nơi nào khác gọi OnItemClick()
.
Điều này làm việc tốt, bởi vấn đề là tôi chuyển sang một ImageButton. Và điều đó không hoạt động như mong đợi. Đối với những người khác, hãy xem câu hỏi này: http://stackoverflow.com/questions/6116583/android-listview-custom-adapter-imagebutton – Henrik