[例证]从滑动冲突到事件分发(从源码角度分析)

本文通过一个ListView在ScrollView中的滑动冲突实例,探讨了事件分发机制以及滑动冲突的原因。分析了ViewGroup的onInterceptTouchEvent()方法,解释了内部拦截法和外部拦截法的原理,详细解读了disallowIntercept的位运算过程,以解决滑动冲突。
摘要由CSDN通过智能技术生成

最近在看安卓开发艺术。看到滑动冲突一章,突然有感。mark一下。

先上一个demo效果图:

上面白色区域是一个listView,外面被一个scrollView包裹着。下面红色区域是一个Linearlayout占位。用来能上下滑动。

布局源码如下:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ListView
            android:id="@+id/list_item"
            android:layout_width="match_parent"
            android:layout_height="200dp"></ListView>
//此处用来占位,能使整个布局达到上下滑动的条件
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="800dp"
            android:background="#ff0000">

        </LinearLayout>
    </LinearLayout>
</ScrollView>
上述布局样式:会发现,listView无法滑动,上下滑动只能滑动外部的scrollView。

问题一、为什么会滑动冲突?

首先先科普一个知识:

1)事件分发机制,是依照Activity——》ViewGroup——》View,从顶部往下分发。

2)而每个ViewGroup当disallowIntercept为false的时候,都会尝试拦截onInterceptTouchEvent()。(ps:后面我会具体谈disallowIntercept这个参数)

从简上盗一张图:点击打开链接 附上事件分发机制的链接。


知道这个知识后,思考一下当前demo,

猜想冲突原因:

分发过程中,被上层的ScrollView拦截了。没有分发到ListView。

我们直接去找ViewGroup拦截的方法onInterceptTouchEvent()。

对于当前demo的布局:activity(忽略)不考虑,直接看最外层ViewGroup类:ScrollView。

发现:ScrollView的onInterceptTouchEvent()继承自FrameLayout,而FrameLayout的onInterceptTouchEvent()原封不动的继承自ViewGroup。所以我直接看ViewGroup的onInterceptTouchEvent()方法:

ViewGroup#onInterceptTouchEvent()源码如下:

public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }
所以ViewGroup默认是不拦截的。而FrameLayout是没有重写这个方法的。再看ScrollView的onInterceptTouchEvent()方法:

ScrollView#onInterceptTouchEvent()源码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值