关于B拦截了子视图C的Move事件B本身不消费,是否上交给上司处理呢?

原创 2017年10月06日 19:42:27

这里需要引入一些小知识:
这里写图片描述

以下做了一个小实验:
1.activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.example.yueyue.myapplication.widgte.MyLinearLayout1
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--MyLinearLayout1不拦截MOVE事件但消费-->
    <!--MyLinearLayout0拦截MOVE事件不消费-->
    <com.example.yueyue.myapplication.widgte.MyLinearLayout0
        android:id="@+id/lyo_content"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/colorAccent"
        android:orientation="vertical">

        <com.example.yueyue.myapplication.widgte.MyCustomView
            android:id="@+id/cv_main"
            android:layout_width="110dp"
            android:layout_height="110dp"/>
    </com.example.yueyue.myapplication.widgte.MyLinearLayout0>

</com.example.yueyue.myapplication.widgte.MyLinearLayout1>

2.MainActivity重写了两个方法:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("xx", "MainActivity的dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("xx", "MainActivity的onTouchEvent");
        return super.onTouchEvent(event);
    }

3.MyCustomView的代码-仅消费Down事件(所以确定为事件的消费者)

public class MyCustomView extends View {

    private Paint paint1;
    private Paint paint2;

    public MyCustomView(Context context) {
        this(context, null);
    }

    public MyCustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        paint1 = new Paint();
        paint1.setColor(Color.GREEN);
        paint1.setStyle(Paint.Style.FILL);


        paint2 = new Paint();
        paint2.setColor(Color.YELLOW);
        paint2.setStyle(Paint.Style.FILL);

        //绘制外层矩形
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint1);
        //绘制内层矩形
        canvas.drawRect(10, 10, getMeasuredWidth() - 10, getMeasuredHeight() - 10, paint2);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean flag = false;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i("xx", "MyCustomView的onTouchEvent--ACTION_DOWN" + event.getAction());
                flag = true;
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("xx", "MyCustomView的onTouchEvent--ACTION_MOVE" + event.getAction());
                flag = false;
                break;
            case MotionEvent.ACTION_UP:
                Log.i("xx", "MyCustomView的onTouchEvent--ACTION_UP" + event.getAction());
                flag = false;
                break;
            default:
                break;

        }

        return flag;
    }


}

3.MyLinearLayout0-拦截事件的MOVE跟UP事件,但仅仅消费UP事件

public class MyLinearLayout0 extends LinearLayout {
    public MyLinearLayout0(Context context) {
        this(context, null);
    }

    public MyLinearLayout0(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLinearLayout0(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean flag = false;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                Log.i("xx", "MyLinearLayout0的 onInterceptTouchEvent ACTION_MOVE" + ev.getAction());
                flag = true;
                break;
            case MotionEvent.ACTION_UP:
                Log.i("xx", "MyLinearLayout0的 onInterceptTouchEvent ACTION_UP" + ev.getAction());
                flag = true;
                break;
            case MotionEvent.ACTION_DOWN:
                Log.i("xx", "MyLinearLayout0的 onInterceptTouchEvent ACTION_DOWN" + ev.getAction());
                flag = false;
                break;
        }
        return flag;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean flag = false;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i("xx", "MyLinearLayout0的onTouchEvent--ACTION_DOWN" + event.getAction());
                flag = false;
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("xx", "MyLinearLayout0的onTouchEvent--ACTION_MOVE" + event.getAction());
                flag = false;
                break;
            case MotionEvent.ACTION_UP:
                Log.i("xx", "MyLinearLayout0的onTouchEvent--ACTION_UP" + event.getAction());
                flag = true;
                break;
            default:
                flag = false;
                break;
        }
        return flag;

    }
}

4.MyLinearLayout1不拦截任何事件,但消费ACTION_MOVE跟UP事件

public class MyLinearLayout1 extends LinearLayout {
    public MyLinearLayout1(Context context) {
        this(context, null);
    }

    public MyLinearLayout1(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLinearLayout1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        Log.i("xx", "MyLinearLayout1的onInterceptTouchEvent--" + event.getAction());
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean flag = false;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i("xx", "MyLinearLayout1的onTouchEvent--ACTION_DOWN" + event.getAction());
                flag = false;
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("xx", "MyLinearLayout1的onTouchEvent--ACTION_MOVE" + event.getAction());
                flag = true;
                break;
            case MotionEvent.ACTION_UP:
                Log.i("xx", "MyLinearLayout1的onTouchEvent--ACTION_UP" + event.getAction());
                flag = true;
                break;
            default:
                flag = false;
                break;
        }
        return flag;

    }
}

实验结果:
这里写图片描述

I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–0
I/xx: MyLinearLayout0的 onInterceptTouchEvent ACTION_DOWN0
I/xx: MyCustomView的onTouchEvent–ACTION_DOWN0
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–2
I/xx: MyLinearLayout0的 onInterceptTouchEvent ACTION_MOVE2
I/xx: MainActivity的onTouchEvent
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–2
I/xx: MyLinearLayout0的onTouchEvent–ACTION_MOVE2
I/xx: MainActivity的onTouchEvent
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–2
I/xx: MyLinearLayout0的onTouchEvent–ACTION_MOVE2
I/xx: MainActivity的onTouchEvent
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–2
I/xx: MyLinearLayout0的onTouchEvent–ACTION_MOVE2
I/xx: MainActivity的onTouchEvent
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–2
I/xx: MyLinearLayout0的onTouchEvent–ACTION_MOVE2
I/xx: MainActivity的onTouchEvent
I/xx: MainActivity的dispatchTouchEvent
I/xx: MyLinearLayout1的onInterceptTouchEvent–1
I/xx: MyLinearLayout0的onTouchEvent–ACTION_UP1

这里可以做个小总结(事件必须要消费):
1.DOWN事件去确定消费者(可能是拦截,然后自己消费了该事件),然后MOVE以及UP分发过程中遇到消费者之后就不再向下传了,如果消费者不消费MOVE或者UP事件,那么就直接传给Activity去处理
2.分发过程中拦截的是DOWN事件(说明这时候还没有消费者),那么其本身的onTouch方法不消费,那么就上传给他的父亲(他父亲不消费,那么又上传给他爷爷),一层层上去直到找到消费者
3.分发过程中拦截的是MOVE事件或者UP事件,,如果其本身不消费MOVE或者UP事件,那么就直接传给Activity去处理,这里也解释了为什么拦截方法是在分发过程中进行拦截的,并且如果你在DOWN retrun true ,则DOWN,MOVE,UP子View都不会捕获事件(作为消费者,优先处理MOVE跟UP事件了);如果你在MOVE return true , 则子View在MOVE和UP都不会捕获事件。
这样设计的目的我觉得是MOVE事件太多了,如果像DOWN事件这样回传,系统负荷太重了


这里有几个大神写的好文章:
1.Android事件分发机制完全解析,带你从源码的角度彻底理解(上) - 郭霖的专栏 - CSDN博客 -两篇
2.Android ViewGroup事件分发机制 - Hongyang - CSDN博客 -张鸿洋的源码级别分析至今我还没有看懂
3.Android中事件分发机制 - qq97206858的博客 - CSDN博客

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

首先是点击事件在不同的布局层次中传递的。 理解Down事件再哪个层次被消费(拦截),后续的Move、Up的点击事件如何传递。 其中ViewGroup中onInterceptTouchEvent方法

首先是点击事件在不同的布局层次中传递的。理解Down事件再哪个层次被消费(拦截),后续的Move、Up的点击事件如何传递。其中ViewGroup中onInterceptTouchEvent方法用来对事...

【HDU5579 2015上海赛区G】【超级大讨论】Game of Arrays a[]+b[]+c[]有些位置可以减一,状态是否可能达成

Game of Arrays Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T...

QSignalMapper分类有序地处理大量信号(就是信号转发机制,A1,A2,A3,....>B>C)

巧用QSignalMapper分类有序地处理大量信号 分类: Qt 2009-06-29 14:39 1840人阅读 评论(1) 收藏 举报 QSignalMapper这个类并...

Fzu 1752 A^B mod C【快速幂+快速积+细节处理】

Problem 1752 A^B mod C Accept: 909    Submit: 3972 Time Limit: 1000 mSec    Memory Limit : 327...

B2C网上商店平台设计的一个细则:处理页面链接转移权重的重要性

大家都知道,为了提高我们网站及电子商务平台的PR(PageRank),所有的站长都在努力的争取大量优质的反向链接。而大部分的反向链接都设定为指向网站的首页。 另一方面,国外的许多SEO专家也曾多...

Codeforces Round #373 (Div. 2) C. Efim and Strange Grade 贪心、实数字符串"a.b"处理

贪心、实数字符串"a.b"处理 每次可以任选择一位进行四舍五入,求中间所有过程中出现的最大的数字。 所以选 '.'右边的第一个 s[i] > '4'的位置,往左进行四舍五入,本次一旦停止了,如果当前位...

Codeforces Round#321 (div.2) A,B,C,D;(细节处理,尺取,dfs(树上的),状态压缩dp)

附上大神链接:http://www.cnblogs.com/alihenaixiao/p/4836471.html#3276283      自己写的A,C,借鉴的大神的B,D; 这个我的头文件习惯...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)