0
点赞
收藏
分享

微信扫一扫

Android 事件分发机制


在结合资料和项目开发过程中遇到的问题(更多好内容戳下面),下面是本人对 Android 事件分发机制的了解:

1. 事件分发的对象是谁?

   答:点击事件( Touch 事件 )。Touch 事件的相关细节(发生触摸的位置、时间等)被封装成 MotionEvent 对象。

2.事件的类型分为几种?

   答:分为四种,具体如下表;

事件类型

具体动作

MotionEvent.ACTION_DOWN

按下 View (所有事件的开始)

MotionEvent.ACTION_UP

抬起 View

MotionEvent.ACTION_MOVE

滑动 View

MotionEvent.ACTION_CANCEL

结束事件 (非人为原因)

3.事件列:手指触摸屏幕到离开屏幕这个过程产生的一系列事件如下;

Android 事件分发机制_点击事件

3.事件在哪些对象之间进行传递?

   答:Activity、ViewGroup、View( Android 的 UI 界面 Activity、ViewGroup、View 以及派生类组成)。

4.事件的分发顺序?

   答:即事件的传递顺序:Activity ==> ViewGroup ==> View 。

5.事件分发过程由哪些主要方法协作完成?

   答:dispatchTouchEvent()、onInterceptTouchEvent() 和 onTouchEvent() 。( 下面是对三个方法的介绍 )

方法

名称

作用

调用时刻

dispatchTouchEvent()

分发事件

分发传递事件

当点击事件能够传递给当前 View 时,该方法会被调用

onInterceptTouchEvent()

拦截事件

判断是否拦截了事件;

默认返回 false 表示不拦截该事件,事件将向下传递(传递给其子View);
若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递,
事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法

在 dispatchTouchEvent() 内部调用

onTouchEvent()

触摸事件

处理点击事件;

返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);
返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理

在 ViewGroup 的 dispatchTouchEvent() 内部调用;

   下面是拥有这三个方法的对象:

对象名称

例子

方法名称

Activity

Activity

dispatchTouchEvent(); 

onTouchEvent();

ViewGroup

LinearLayout

dispatchTouchEvent();

onInterceptTouchEvent();

onTouchEvent();

View

TextView

dispatchTouchEvent();

onTouchEvent();

6.工作流程的总结:

Android 事件分发机制_Android 事件分发机制_02

7.核心方法的总结:


Android 事件分发机制_事件分发机制_03

8.Demo(demo):

//Activity 即第一层
public class MainActivity extends Activity {

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第一层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第一层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第一层" + "往下分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第一层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第一层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean t = false;
        Log.e("e", "第一层" + "能解决吗" + t);
        return t;
    }
}

//ViewGroup 即第二层
public class MyLinearLayout extends LinearLayout {

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第二层" + "往下分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第二层" + "需要拦截吗" + b);
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第二层" + "能解决吗" + b);
        return b;
    }
}

//View 即第三层
@SuppressLint("AppCompatCustomView")
public class MyTextView extends TextView{

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("e","第三层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e","第三层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第三层"+"往下分派事件?我是最底层,没有办法分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("e","第三层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e","第三层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第三层"+"能解决吗"+b);
        return b;
    }
}

下面是分发走的顺序:

Android 事件分发机制_Android 事件分发机制_04

至此,应该对事件分发机制有一定了解,demo下载地址

如果有更好的见解或补充点下面喔

举报

相关推荐

0 条评论