安卓学习笔记之事件分发机制

触摸事件的分发机制

安卓的UI界面是一种树形壮结构的。层层嵌套组件,既然是很多组件嵌套在一起,倘若组件之间层层叠加,都有各自的触摸事件,当我们点击的时候,就不知道是哪个组件做出的响应。所以有了事件的分发机制。

主要有三个方法:

dispatchTouchEvent()

onTouchEvent()

onInterceptEvent()

用代码来实际演示各自代表什么意思。

这里写图片描述

图片来自http://www.jianshu.com/p/38015afcdb58


Demo

这里写图片描述

我自定义了一个ViewGroup继承自FrameLayout,里面包含这ChildView这个子空间,最外面则是Activity。

为了避免重复的代码,我写了一个工具类。

public class TouchUtil {

    public static void logTouch(MotionEvent event, String name) {
        int action = event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                Log.i("does",name+"ACTION_DOWN 响应");
                break;
            case MotionEvent.ACTION_UP:
                Log.i("does",name+"ACTION_UP 响应");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("does",name+"ACTION_MOVE 响应");
                break;
        }
    }
}

ParentView

public class ParentViewGroup extends FrameLayout {
    public ParentViewGroup(@NonNull Context context) {
        super(context);
    }

    public ParentViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        TouchUtil.logTouch(event,"ParentView onTouchEvent -------");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        TouchUtil.logTouch(ev,"Dispatch ParentView ---------");
//        return super.dispatchTouchEvent(ev);
        return super.dispatchTouchEvent(ev);
    }

}

ChildView

public class ChildView extends View {
    public ChildView(Context context) {
        super(context);
    }

    public ChildView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        TouchUtil.logTouch(event,"ChildView onTouchEvent -------");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        TouchUtil.logTouch(ev,"Dispatch childView---------");
        return super.dispatchTouchEvent(ev);
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        TouchUtil.logTouch(event,"MainActivity onTouchEvent -------");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        TouchUtil.logTouch(ev,"Dispatch Activity --------");
        return super.dispatchTouchEvent(ev);
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f00"
    tools:context="com.example.touch.MainActivity">

    <com.example.touch.ParentViewGroup
        android:layout_width="300dp"
        android:layout_centerInParent="true"
        android:layout_height="300dp"
        android:background="#0f0"
        >
        <com.example.touch.ChildView
            android:layout_gravity="center"
            android:background="#00f"
            android:layout_width="150dp"
            android:layout_height="150dp" />


    </com.example.touch.ParentViewGroup>
</RelativeLayout>

当我们运行程序的时候会,当我们点击ChildView的时候,输出日志信息,

08-25 05:34:28.599 31190-31190/com.example.touch I/does: Dispatch Activity ——–ACTION_DOWN 响应
08-25 05:34:28.600 31190-31190/com.example.touch I/does: Dispatch ParentView ———ACTION_DOWN 响应
08-25 05:34:28.600 31190-31190/com.example.touch I/does: Dispatch childView———ACTION_DOWN 响应
08-25 05:34:28.600 31190-31190/com.example.touch I/does: ChildView onTouchEvent ——-ACTION_DOWN 响应
08-25 05:34:28.600 31190-31190/com.example.touch I/does: ParentView onTouchEvent ——-ACTION_DOWN 响应
08-25 05:34:28.600 31190-31190/com.example.touch I/does: MainActivity onTouchEvent ——-ACTION_DOWN 响应
08-25 05:34:28.695 31190-31190/com.example.touch I/does: Dispatch Activity ——–ACTION_UP 响应
08-25 05:34:28.695 31190-31190/com.example.touch I/does: MainActivity onTouchEvent ——-ACTION_UP 响应

从上面Log日志当中我们可以知道。
dispatchEvent表示的是事件的一个分发机制方法,表示从外向里分发事件。默认返回为false,所以先执行dispatch事件。
这里写图片描述
当事件分发结束之后,处理TouchEvent事件,触摸事件则向上传递。默认返回的值为false。
这里写图片描述

onInterceptTouchEvent

这个函数代表的是拦截事件,顾名思义,默认返回的就是false,如果返回为true说明在当前view上进行拦截触摸事件。比如我在ParentView重写onInterceptTouchEvent方法并返回为true,则表示事件不再往下传递,通俗来说就是没ChildView什么事情了。但是这需要注意的是,只有viewGroup才有!!

这三个方法,用一个表格来说明
这里写图片描述
图片来自http://www.jianshu.com/p/38015afcdb58

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值