Tôi gặp sự cố tương tự và mất 2 ngày để gỡ lỗi và giải quyết vấn đề. Tôi có một ListAdapter mà tạo ra một số TextViews trong một LinearLayout cho mỗi mục danh sách. Mỗi TextView có OnClickListener của riêng nó, bởi vì tôi cần phải xử lý các nhấp chuột trên mỗi mục.
Khi tôi thay đổi triển khai để tôi sử dụng lại Chế độ xem, OnClickListener đã ngừng hoạt động chính xác. Ngày 4.4.2, hầu hết các nhấp chuột đều hoạt động nhưng đôi khi không có phản ứng nào cho đến khi tôi cuộn trong danh sách. Vào ngày 2,3, các nhấp chuột đầu tiên sẽ không hoạt động và sau đó tất cả các nhấp chuột được xử lý trong một cụm.
Trong trường hợp đặc biệt của tôi, tôi đã tạo tất cả mã Xem bằng Java và không phải bằng cách tăng nguồn tài nguyên. Và điểm quan trọng là, tôi đã đặt LayoutParams của LinearLayout ngay cả khi chế độ xem được sử dụng lại (điều này có vẻ an toàn hơn, giả sử rằng chế độ xem được sử dụng lại có thông số bố cục chính xác). Khi tôi không đặt LayoutParams khi sử dụng lại mọi thứ hoạt động tốt! Đây là mã quan trọng:
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout tapeLine = null;
if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view
else tapeLine = new LinearLayout(activity);
if (convertView == null) { // Don't set LayoutParams when reusing view
ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tapeLine.setLayoutParams(tapeLineLayoutParams);
}
ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape();
int tapeWidthPx = parent.getWidth();
TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx);
ScrollingTapeLine line = scrollingTape.getLine(position);
tapeLine.setOrientation(LinearLayout.HORIZONTAL);
int tapeBackgroundColor = getBackgroundColor(line);
tapeLine.setBackgroundColor(tapeBackgroundColor);
addColumnViews(tapeLine, line, tapeLineTextSizeInfo);
tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position);
tapeLine.setOnLongClickListener(longClickListener);
tapeLine.setOnClickListener(remainClickListener);
return tapeLine;
}
Nền của hành vi kỳ lạ này trong chế độ xem danh sách là gì? Tôi đã làm một chút gỡ lỗi và nghiên cứu trong các nguồn Android. Khi Android cập nhật chế độ xem, có hai bước quan trọng trênMeasure và onLayout. Phương thức getView của ListAdapter không chỉ được gọi để vẽ khung nhìn mà còn được gọi trước đó trong khi onMeasure. Trong trường hợp sau này, khung nhìn được tạo nhưng nó chưa được đăng ký trong chuỗi sự kiện để xử lý các sự kiện nhấp chuột.
Khi chế độ xem đã được tạo cho onMeasure được tái sử dụng sau này để được vẽ một cách chính xác vào màn hình, nó phải được đăng ký từ hệ thống Android để xử lý các sự kiện nhấp. Đối với trường hợp đặc biệt này, những người phát triển Android đã làm điều gì đó, có thể được xem là một hack bẩn. Một lá cờ đặc biệt trong LayoutParams được sử dụng để quyết định rằng khung nhìn phải được đăng ký trong sự kiện thay đổi.
Bây giờ vấn đề của tôi: bằng cách đặt lại LayoutParams cũng khi chế độ xem được sử dụng lại, cờ này luôn được đặt lại. Do đó hệ thống Android sẽ không đăng ký xem và các sự kiện sẽ không đi qua.
để tóm tắt: khi sử dụng lại chế độ xem trong getView của ListAdapter không ghi đè lên LayoutParams vì chúng giữ thông tin nội bộ của hệ thống android.
Tôi sử dụng Trình tải đặc biệt AsyncLoader để thực hiện tất cả các quy trình nền của tôi. Nhưng tôi sẽ đánh giá lại mã, nhờ mẹo! – Bostone
Chẳng phải là lý do. Xem câu trả lời của tôi – Bostone