从ListView与ScrollView的冲突调查android view的事件处理机制

当我们做项目时经常会遇到整体界面需要滑动,此页面中又有ListView的 情况。比如说:某法院系统的提交诉讼材料界面,这种界面要提交很多元素,其中想证人可能有多个,就会用到ListView。但这种ScrollView里 包含ListView的情况下,ListView是无法滚动的。很多人都知道这个现象,但为什么会出现这个问题呢?这就要追溯到我们今天要讲的 android View的事件处理机制。

首先我们先看这个问题为什么会产生呢?我们调查ScrollView的代码会发现,如下

public boolean onInterceptTouchEvent(MotionEvent ev) {

    final int action = ev.getAction();
    if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
        return true;
    }
}

这个方法是touch事件的拦截方法,当用户拖动屏幕,就会被这个方法拦截下来,返回true,所以ListView的滚动就失效了。这里又扯出onInterceptTouchEvent方法,这个方法又是什么呢?

View整个体系提供了3个对事件操作:

  1. dispatchTouchEvent。事件分发,主要是体系的上层向下层,层级形式分发事件的机制。
  2. onInterceptTouchEvent。事件拦截,主要是拦截事件,并阻止其进一步传递到体系下层的机制。
  3. onTouchEvent。事件处理,主要是事件接收并做出处理,并向体系上层传递处理结果的机制。

通过这三种操作,对View体系中的事件作出管理。那我们现在已经知道了问题出现的原因:是因为用户的拖动事件被ScrollView的onInterceptTouchEvent方法拦截住了,那事件又是怎么传递过来的呢?

当手机屏幕被用户触摸,就会形成一套事件序列,每一套事件序列都有三种事件动作(down,move,up)组合完成。 这套序列会被传递到系统framework层,再传入Activity,然后Activity会把事件传给Window下的DecorView进行分发, 分发给每个View。而某个View的onTouchEvent处理了这个事件,并返回true,就说明此事件已传递完毕。

说到返回值,这三个方法的返回值含义如下:

  • dispatchTouchEvent
    true:事件被以该节点为根节点的View树成功处理,此时该事件就算是处理完成了,事件不会再向上返还给View的父节点。
    false:以该节点为根节点的View树中,没有一个View成功处理了此事件,所以事件会向上返还给View的父节点。
  • onInterceptTouchEvent
    true:当前ViewGroup希望该事件不再传递给其下层,而是希望自己处理。
    false:当前ViewGroup不准备拦截该事件,事件将正常向下分发给其下层。

  • onTouchEvent
    true:表示该View成功处理了该事件,该处理结果会向上通知给其上层。
    false:表示该View没有成功处理该事件。

到此,了解了这么多再回顾一下开始的问题,原因是事件被ScrollView拦截到了,那解决方法有很多,最直接的一种就是当我们滑动ListView时不让ScrollView拦截到。那要怎么做呢?

通知其上层不要拦截此事件。代码如下:

public boolean onTouchEvent(MotionEvent ev) {  
    super.onTouchEvent(ev);  
    switch (ev.getAction()) {  
        case MotionEvent.ACTION_DOWN:  
            getParent().requestDisallowInterceptTouchEvent(true);  
            break;  
        case MotionEvent.ACTION_MOVE:  
            break;  
        case MotionEvent.ACTION_UP:  
            getParent().requestDisallowInterceptTouchEvent(false);  
            break;  
        default:  
            break;  
    }  
    return  true;  
}

以上就是从ListView与ScrollView的冲突调查android view的事件处理机制,希望对大家有所帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值