1. 程式人生 > >Recyclerview或Listview實時重新整理,item點選事件失效的解決方法

Recyclerview或Listview實時重新整理,item點選事件失效的解決方法

問題場景:

本人最近在做一個關於藍芽開發的Demo,在掃描藍芽裝置的時候會產生回撥,並會返回BluetoothDevice和rssi,這個rssi就是掃描到的這個裝置的訊號。
這裡寫圖片描述
注意,這個回撥不是搜尋到1個裝置後就只回調一次這個裝置,而是隻要掃描到了就會回撥,如下圖,掃描到了很多重複的裝置。
這裡寫圖片描述
所以,這樣的話,我們就可以實時的拿到rssi,進行訊號的實時重新整理。
然後我把每一個裝置都當做一個item放在了Recyclerview裡,因為要實時重新整理rssi(訊號),所以就要一直呼叫
mAdapter.notifyDataSetChanged()來實現。
這裡寫圖片描述

具體問題:

那麼問題來了,在掃描中的時候,訊號會實時重新整理,然後設定了OnItemClickLitener,但是點選會失效。在我停止了掃描,也就是沒有回撥的時候,自然不會呼叫mAdapter.notifyDataSetChanged()來進行實時重新整理了,這時點選不會失效。

解決問題:

我先對item設定了一個OnItemTouchListener(),具體程式碼

        mAdapter.setOnItemTouchListener(new MyAdapter.OnItemTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i(TAG, "Item: ACTION_DOWN"
); break; case MotionEvent.ACTION_MOVE: Log.i(TAG, "Item: ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.i(TAG, "Item: ACTION_UP"); break
; case MotionEvent.ACTION_CANCEL: Log.i(TAG, "Item: ACTION_CANCEL"); break; } return false; } });

重新執行一遍,在掃描中的時候,點選item,檢視日誌。
這裡寫圖片描述
發現item的事件走到了DOWN後就直接到了CANCEL,並沒有走到UP,那就不可能到Click了。
那我停止掃描裝置,也就是不實時重新整理了,點選item,檢視日誌。
這裡寫圖片描述
發現item的事件正常的經過了DOWN和UP,然後到了Click,經過這個測試,我們可以猜測或大致的先認為點選item失效,是由notifyDataSetChanged()引起的,我們看看能不能解決。
需要注意的時,通過日誌我們可以發現,雖然Click失效了,但是onTouch並沒有失效,點選的時候每次都會走到ACTION_DOWN裡,這裡我們就有了一個解決方法,就是定義一個標記isClick,然後把mAdapter.notifyDataSetChanged()放在if(!isClick){}裡去執行,在MotionEvent.ACTION_DOWN的時候,isClick=true,在case MotionEvent.ACTION_UP的時候,isClick=false,具體程式碼:

        if (!isClick) {
            mAdapter.notifyDataSetChanged();  //重新整理資料
        }
        mAdapter.setOnItemTouchListener(new MyAdapter.OnItemTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        isClick = true;
                        Log.i(TAG, "Item: ACTION_DOWN");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i(TAG, "Item: ACTION_MOVE");
                        break;
                    case MotionEvent.ACTION_UP:
                        isClick = false;
                        Log.i(TAG, "Item: ACTION_UP");
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        Log.i(TAG, "Item: ACTION_CANCEL");
                        break;
                }
                return false;
            }
        });

執行測試,實時重新整理的時候點選,檢視日誌
這裡寫圖片描述
可以發現點選生效了,但還能發現,最後一下點選沒有生效,還是走到了DOWN直接到了CANCEL,並沒有走到UP,而且更為致命的是,訊號不重新整理了,因為我們再DOWN裡isClick = true裡,但是沒有走到UP裡,所以isClick就一直為true了,就不會呼叫notifyDataSetChanged()了, 解決辦法是我們在CANCEL裡也加上isClick = false。

總結:

通過這個方法可以解決在實時重新整理的時候點選失效的問題,但是,還是會有點選失效的問題,不過在實際操作過程中沒有明顯的感覺。具體的更好的解決辦法目前還沒有發現。