Recyclerview或Listview实时刷新,item点击事件失效的解决方法

问题场景:

本人最近在做一个关于蓝牙开发的Demo,在扫描蓝牙设备的时候会产生回调,并会返回BluetoothDevice和rssi,这个rssi就是扫描到的这个设备的信号。
Recyclerview或Listview实时刷新,item点击事件失效的解决方法_第1张图片
注意,这个回调不是搜索到1个设备后就只回调一次这个设备,而是只要扫描到了就会回调,如下图,扫描到了很多重复的设备。
Recyclerview或Listview实时刷新,item点击事件失效的解决方法_第2张图片
所以,这样的话,我们就可以实时的拿到rssi,进行信号的实时刷新。
然后我把每一个设备都当做一个item放在了Recyclerview里,因为要实时刷新rssi(信号),所以就要一直调用
mAdapter.notifyDataSetChanged()来实现。
Recyclerview或Listview实时刷新,item点击事件失效的解决方法_第3张图片

具体问题:

那么问题来了,在扫描中的时候,信号会实时刷新,然后设置了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,查看日志。
Recyclerview或Listview实时刷新,item点击事件失效的解决方法_第4张图片
发现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;
            }
        });

运行测试,实时刷新的时候点击,查看日志
Recyclerview或Listview实时刷新,item点击事件失效的解决方法_第5张图片
可以发现点击生效了,但还能发现,最后一下点击没有生效,还是走到了DOWN直接到了CANCEL,并没有走到UP,而且更为致命的是,信号不刷新了,因为我们再DOWN里isClick = true里,但是没有走到UP里,所以isClick就一直为true了,就不会调用notifyDataSetChanged()了, 解决办法是我们在CANCEL里也加上isClick = false。

总结:

通过这个方法可以解决在实时刷新的时候点击失效的问题,但是,还是会有点击失效的问题,不过在实际操作过程中没有明显的感觉。具体的更好的解决办法目前还没有发现。

参考:
http://blog.csdn.net/qq_35522272/article/details/52188141

你可能感兴趣的:(Android)