17

Tôi có cấu trúc sau đây trong ứng dụng của tôi:Android - nhấp chuột trì hoãn trong ListView

FragmentActivity với ViewPager giữ nhiều mảnh bởi FragmentStatePagerAdapter quản lý sử dụng gói compativility với Android 2.1

Mỗi mảnh chứa ListView. Mỗi phần tử trong ListView có một LinearLayout với hai TextViews và một Button. LinearLayout và nút có onClickListeners (riêng biệt). Nhấp vào số LinearLayout bắt đầu một số Activity khác. Tôi nhận thấy rằng hành vi nhấp chuột rất không nhất quán: đôi khi hành động được thực hiện ngay lập tức nhưng rất thường bị trì hoãn và đôi khi nó bị bỏ qua bất kể tôi nhấn bao nhiêu lần. Nó thậm chí còn khó hơn vì tôi có thể nhấn và hành động sẽ chỉ được thực hiện khi tôi bắt đầu cuộn danh sách. Tôi đã thử các kết hợp khác nhau của setFocusable(false)setSelectable(true) nhưng dường như không tạo ra bất kỳ sự khác biệt nào. Ý tưởng nào? Tôi rất sẵn lòng cung cấp thêm chi tiết.

Trả lời

3

Trong trường hợp ai đó tự hỏi làm thế nào tôi đã giải quyết vấn đề này. Về cơ bản tôi đã phải đơn giản hóa bố trí của tôi. Có vẻ như khi bạn có các sự kiện cấu trúc lồng nhau phức tạp có thể mất quá nhiều thời gian để bong bóng và nếu bạn bắt đầu cuộn danh sách tại cùng một sự kiện thời gian có thể kích hoạt hành động sai. Tôi đã cắt bớt bố trí bằng cách chuyển sang RelativeLayout càng nhiều càng tốt và dường như giúp đỡ rất nhiều

-1

Có vẻ như bạn đang thực hiện một số quy trình chặn (như gọi các dịch vụ web hoặc mở tệp) trong chuỗi sự kiện, do đó chuỗi Sự kiện của bạn bị chặn. Nếu trường hợp này xảy ra, Vui lòng xử lý mã chặn của bạn vào một chuỗi khác so với Sự kiện đã đọc.

+0

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

+0

Chẳng phải là lý do. Xem câu trả lời của tôi – Bostone

4

Tôi gặp phải vấn đề tương tự, nhưng trong trường hợp của tôi, giải pháp không giữ nguyên tham chiếu đến chế độ xem. bộ nhớ đệm. Sau khi triển khai đúng phương thức getView() với việc sử dụng converView, tất cả hành vi lạ với các cuộc gọi nhấp bị mất/không mong muốn đã biến mất.

+0

Tôi luôn sử dụng mẫu trình xử lý trong mã của mình khi xử lý danh sách – Bostone

+0

+1 hoạt động đối với tôi. Tôi đã giữ một tham chiếu đến một trong các chế độ xem của tôi (sau đó được sử dụng cho một hàng 'ListView') vì lý do tôi không đi vào đây - vì lý do nào đó có tác dụng trì hoãn tất cả nhấp chuột vào mục đó cho đến khi hoạt động * * được khởi động lại ** nơi chúng sẽ chạy qua và gây ra một loạt các ngoại lệ. tạo ra khung nhìn bên trong bộ điều hợp giải quyết vấn đề này - rất lạ – Dori

1

Điều gì đã hiệu quả đối với tôi là chỉ định OnItemClickListener cho ListView thông qua setOnItemClickListener, chứ không phải là OnClickListener cho các mục danh sách riêng lẻ. Rõ ràng là nút vẫn cần OnClickListener riêng của mình nhưng tôi chưa thử nghiệm kịch bản đó.

9

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.

+0

Tôi đã có cùng một vấn đề. Trong trường hợp của tôi, bố cục phải thay đổi kích thước dựa trên nguồn dữ liệu cho danh sách, vì vậy lần đầu tiên chế độ xem được tăng cao, tôi đã thay đổi layout.params và nhấp vào các mục hàng đã hoạt động tốt một lần nữa. –

+0

OM * G, không đời nào, đó là nó dành cho tôi! Đó là soooo backwards, tối nghĩa và hết sức não chết. Một API là một hợp đồng và cái này không được tôn trọng. Tôi đã mất hàng giờ về điều này, đừng để nhà phát triển Google ở ​​gần tôi. Cảm ơn vì đã không để tôi phát điên lên. –

1

Bạn không chắc chắn điều này có giúp ích gì cho ai không, nhưng thay vào đó tôi gặp vấn đề tương tự với TableLayout. Các giải pháp trên không khắc phục được sự cố của tôi.

Đối với tôi vấn đề là: android:animateLayoutChanges="true"

Loại bỏ điều này cho phép nhấp chuột vào nút của tôi trong hàng TableLayout của tôi hoạt động tốt. Sau đó, tôi phải tạo ảnh động theo cách thủ công thay vì dựa vào thuộc tính ở trên.

+0

tắt hoạt ảnh cũng hoạt động cho tôi. –

Các vấn đề liên quan