View的事件分发机制【原创】

栏目: IOS · Android · 发布时间: 5年前

内容简介:view的事件分发主要依靠的是Android中的MotionEvent类。事件分发就是对 MotionEvent事件分发的过程。分发过程主要是由三个方法共同完成的:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。先分别介绍一下这三个方法。这个方法从取名上就可以看出来是分发事件的意思。如果事件能传递给当前的View时,该方法一定会被调用。返回结果受当前View的onTouchEvent和下级的dispatchTouchEvent方法影响,表示是否消耗

view的事件分发主要依靠的是Android中的MotionEvent类。事件分发就是对 MotionEvent事件分发的过程。分发过程主要是由三个方法共同完成的:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。先分别介绍一下这三个方法。

public boolean dispatchTouchEvent(MotionEvent ev)

这个方法从取名上就可以看出来是分发事件的意思。如果事件能传递给当前的View时,该方法一定会被调用。返回结果受当前View的onTouchEvent和下级的dispatchTouchEvent方法影响,表示是否消耗当前的事件。

public boolean onInterceptTouchEvent(MotionEvent ev)

该方法从取名上也可以知道是阻止触摸事件的意思。其实就是是否拦截某个事件的意思。如果当前View拦截了某个事件,那么在同一个事件序列中,此方法就不会再次被调用。返回的结果表示是否拦截当前事件。

public boolean onTouchEvent(MotionEvent ev)

此方法实在dispatchTouchEvent方法中调用,用来处理事件的。返回结果表示是否消耗当前事件。如果不消耗,同一个事件序列,当前View无法再次接受事件。

以上是对三个方法的介绍,从这三个方法中可以看出来View的事件分发,有三个阶段:分发,拦截,消费。下面说一下触摸事件对应的MotionEvent类。它的类型主要分为 三种:ACTION_DOWN、ACTION_MOVE、ACTION_UP。

  • ACTION_DOWN:用户手指的按下操作,一个按下操作意味着一次触摸事件的开始。
  • ACTION_MOVE:用户手指按压屏幕后,在松开之前,如果移动的距离超过一定的值,那么会被判定为ACTION_MOVE操作,一般情况下,手指的轻微一定都会触发一系列的移动事件。
  • ACTION_UP:用户手指离开屏幕的操作,一次抬起操作标志一次触摸事件的结束。

View在Android中只拥有dispatchTouchEvent和onTouchEvent两个方法。ViewGroup是View的子类。但是这里所指的View是指除ViewGroup外的View控件。

举例说明一下:

新建一个工程,先写个MyTextView继承AppCompatTextView,代码如下:

public class MyTextView extends AppCompatTextView {

    private static final String TAG = "MyTextView";

    public MyTextView(Context context) {
        super(context);
    }

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "dispatchTouchEvent   ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "dispatchTouchEvent   ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "dispatchTouchEvent   ACTION_UP");
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "onTouchEvent   ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "onTouchEvent   ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "onTouchEvent   ACTION_UP");
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
}

接着修改一下布局文件,将TextView修改为MyTextView,然后修改MainActivity,代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {
    private static final String TAG = "MainActivity";
    private MyTextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (MyTextView) findViewById(R.id.textView);
        mTextView.setOnClickListener(this);
        mTextView.setOnTouchListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.textView:
                Log.i(TAG, "MyTextView onclick");
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (view.getId()) {
            case R.id.textView:
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i(TAG, "MyTextView  onTouch   ACTION_DOWN");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i(TAG, "MyTextView  onTouch   ACTION_MOVE");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i(TAG, "MyTextView  onTouch   ACTION_UP");
                        break;
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "dispatchTouchEvent   ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "dispatchTouchEvent   ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "dispatchTouchEvent   ACTION_UP");
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i(TAG, "onTouchEvent   ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i(TAG, "onTouchEvent   ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG, "onTouchEvent   ACTION_UP");
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
}

运行项目,查看log:

com.bob.viewtestdemo I/MainActivity: dispatchTouchEvent ACTION_DOWN

com.bob.viewtestdemo I/MyTextView: dispatchTouchEvent ACTION_DOWN

com.bob.viewtestdemo I/MainActivity: MyTextView onTouch ACTION_DOWN

com.bob.viewtestdemo I/MyTextView: onTouchEvent ACTION_DOWN

com.bob.viewtestdemo I/MainActivity: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: MyTextView onTouch ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: onTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: MyTextView onTouch ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: onTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: dispatchTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: MyTextView onTouch ACTION_MOVE

com.bob.viewtestdemo I/MyTextView: onTouchEvent ACTION_MOVE

com.bob.viewtestdemo I/MainActivity: dispatchTouchEvent ACTION_UP

com.bob.viewtestdemo I/MyTextView: dispatchTouchEvent ACTION_UP

com.bob.viewtestdemo I/MainActivity: MyTextView onTouch ACTION_UP

com.bob.viewtestdemo I/MyTextView: onTouchEvent ACTION_UP

com.bob.viewtestdemo I/MainActivity: MyTextView onclick

总结一下,

  • 用户点击屏幕ACTION_DOWN执行MainActivity的dispatchTouchEvent,看返回值,如果是super方法,执行MyTextView的dispatchTouchEvent;如果返回的是true或者是false,将不再继续分发ACTION_DOWN事件,同时不会调用 MainActivity的MyTextView onclick。
  • 执行MyTextView的dispatchTouchEvent,看返回值,如果是super方法,执行MainActivity的MyTextView onTouch;如果返回的是true或者false,当返回的是true时,将不再继续分发ACTION_DOWN事件,同时不会调用 MainActivity的MyTextView onclick,当返回的是false时,执行MainActivity的onTouchEvent。
  • 执行MainActivity的MyTextView onTouch,返回值为true时,将不再继续分发ACTION_DOWN事件,同时不会调用 MainActivity的MyTextView onclick,返回值为false时,执行MyTextView的onTouchEvent。
  • 执行MyTextView的onTouchEvent。看返回值,如果返回值是super方法,ACTION_DOWN传递完成,如返回值是true或false,当返回值为true时,ACTION_DOWN传递完成,当返回值为false时,执行MainActivity的onTouchEvent。
  • 执行MainActivity的onTouchEvent,代表ACTION_DOWN传递完成。

转载时请注明出处及相应链接,本文永久地址:https://blog.yayuanzi.com/25097.html

View的事件分发机制【原创】

View的事件分发机制【原创】 微信打赏

View的事件分发机制【原创】 支付宝打赏

感谢您对作者Bob的打赏,我们会更加努力!    如果您想成为作者,请点我


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web全栈工程师的自我修养

Web全栈工程师的自我修养

余果 / 人民邮电出版社 / 2015-9-1 / 49.00

全栈工程师正成为 IT 行业的新秀,论是上市互联网公司还是创业公司,都对全栈工程师青睐有加。本书作者是腾讯公司高级工程师,在前端、后端和APP开发方面都有丰富的经验,在本书中分享了全栈工程师的技能要求、核心竞争力、未来发展方向、对移动端的思考。除此之外,本书还详细记录了作者从零开始、学习成长的心路历程。 本书内容全面,客观务实,适合互联网行业新人、程序员,以及期待技术转型的从业者阅读参考。一起来看看 《Web全栈工程师的自我修养》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试