android 事件分发,解决由于listview中实时刷新,导致子view点击事件失效

近期由于个人的某些因素作怪,导致没有很好地总结和积累,主要是最近一段时间,大多数接触的都是第三方的sdk ,在一些接口问题上造成了很多困扰,很是麻烦,并且说明文档也不详细,所以每每遇到一些问题都要等待很久才能解决。
好了,废话不多说了。下面开始今天的正文。(最近发现这个问题好像网上解决的并不多,啰嗦太多不好意思哈,想知道解决办法,可以直接看最后一段)android 之事件分发机制。并且结合本人开发中遇到的实际场景来说明一下解决办法。
本人近期在做文件的上传和下载,这个必定会用到progressBar 进度条,因为这个是描述下载和上传进度的最显著的体现。我将每条记录放入listview的item中,所以每个item中必定需要包含进度条。进度条这个东西当然是实时更新的。更新频率也非常的高,所以每次进度有更新我都会进行adapter.notifySetDatachange 这样才能实时看到界面变化,那么问题来了。我们在上传下载过程中肯定需要对这个任务进行暂停或开始的操作,这些按钮也是在每个item中都存在的。那么在任务进行中的时候,我想点击暂停按钮,把任务暂停。但是发现无论怎么点击,onclick中的代码都不会执行,这个让我感到很奇怪。排除了一些基本的问题,我想到了会不会是由于实时刷新页面导致点击事件失效。
看一下效果图吧:这里写图片描述
想到这里我就想写一个demo来测试一下。
首先我们都知道安卓的触屏事件其实都是通过

 public boolean dispatchTouchEvent(MotionEvent ev) {}

这个事件分发机制来实现。首先这个分发都是从activity中的windowManager来开始的,

  @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e(TGA,"dispatchTouchEvent_ACTION_DOWN");

//                return  false;
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TGA,"dispatchTouchEvent_ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:
                Log.e(TGA,"dispatchTouchEvent_ACTION_UP");

//                return  false;

            case MotionEvent.ACTION_CANCEL:
                Log.e(TGA,"dispatchTouchEvent_ACTION_CANCEL");

                break;
        }
        return super.dispatchTouchEvent(ev);
    }

事件的从actionDown开始的,如果在activity 中有View来接受这个down事件,那么这个事件就会传给view的分发,其中还有ViewGroup ,因为它有子View 所以此时又会有事件传递,查看是否有子View接受这个事件,如果没有那就自己消费掉。假设就是一个button那么就不用分发了,直接自己消费就可以,自己消费的话就是在View的ontouchEvent中进行触发。

 button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        Log.e(TGA,"ACTION_DOWN");

                        break;

                    case MotionEvent.ACTION_MOVE:
                        Log.e(TGA,"ACTION_MOVE");

                        break;

                    case MotionEvent.ACTION_UP:
                        Log.e(TGA,"ACTION_UP");

                        break;

                    case MotionEvent.ACTION_CANCEL:
                        Log.e(TGA,"ACTION_CANCEL");

                        break;

                }
                return false;
            }
        });

所以很容易理解,事件就是一件一件传递下去那么我们的Onclick事件是什么时候触发呢,这个就是在MotionEvent 中的Action_UP之后便会触发,就是当你的收抬起来之后click事件才真正执行。首先我们看一下demo的源码:

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值