MotionEvent 说明

MotionEvent 说明

完整touch event流程

Android用于描述动作的封装类。这里的动作不仅包含touch event,还有如鼠标、手柄等不同输入设备所触发的动作,下文以touch event为例。
该类将一个动作描述为动作码action code和一些系列坐标值。当手指触碰屏幕时,首先产生动作码为ACTION_DOWN的MotionEvent,随后ACTION_MOVE记录手指在屏幕上的滑动信息,当手指离开屏幕时产生ACTION_UP,此时一个touch event就正常结束了。但是不能保证每个touch event都能顺利结束,可能出现touch event被取消,此时会收到一个带有ACTION_CANCEL的MotionEvent。

Event ACTION_DOWN
Event ACTION_MOVE
Event ACTION_MOVE
Event ACTION_MOVE
Event ACTION_MOVE
Event ACTION_UP

支持多点触碰

Android引入了pointer来描述每一个触碰点。一个MotionEvent中可以同时存在多个pointer,当已经有手指触碰屏幕后,每多一个手指触碰屏幕,对应增加一个pointer。为了区分不同的pointer,每个pointer都带有一个id,并且保证id在整个touch event有效期间保持不变。

I/history: --------------once history start!-----------
I/history: At time 87122940
I/history: pointer 0: (650.0,593.0)
I/history: pointer 1: (278.0,878.0)
I/history: At time 87122948
I/history: pointer 0: (653.0,614.0)
I/history: pointer 1: (281.0,904.0)
I/history: At time 87122957
I/history: pointer 0: (658.0,642.0)
I/history: pointer 1: (284.0,934.0)
I/history: At time 87122965
I/history: pointer 0: (661.0,670.0)
I/history: pointer 1: (289.0,968.0)
I/history: Current time :87122969
I/history: pointer 0: (661.4655,685.3621)
I/history: pointer 1: (290.8621,983.3622)
I/history: --------once history finish--------- 
I/history: --------------once history start!-----------
I/history: At time 87122973
I/history: pointer 0: (662.0,703.0)
I/history: pointer 1: (293.0,1001.0)
I/history: At time 87122982
I/history: pointer 0: (664.0,737.0)
I/history: pointer 1: (297.0,1038.0)
I/history: Current time :87122989
I/history: pointer 0: (664.0,765.4084)
I/history: pointer 1: (298.7755,1062.8573)
I/history: --------once history finish--------- 

对于ACTION_MOVE,Android会将多个ACTION_MOVE集合在一个MotionEvent中。以下是源码中给出的按时间顺序查看MotionEvent中全部pointer代码,运行结果见上。

    void printSamples(MotionEvent ev) {
        final int historySize = ev.getHistorySize();
        final int pointerCount = ev.getPointerCount();
        Log.i("history", "--------------once history start!-----------");
        for (int h = 0; h < historySize; h++) {
            Log.i("history","At time "+ev.getHistoricalEventTime(h) );
            for (int p = 0; p < pointerCount; p++) {
                Log.i("history","index "+ev.findPointerIndex(p)+" pointer "+ev.getPointerId(p)+": ("+ev.getHistoricalX(p, h)+","+ev.getHistoricalY(p, h)+")");
            }
        }
        Log.i("history","Current time :"+ev.getEventTime());
        for (int p = 0; p < pointerCount; p++) {
            Log.i("history","index "+ev.findPointerIndex(p)+" pointer "+ev.getPointerId(p)+": ("+ ev.getX(p)+","+ev.getY(p)+")");
        }

        Log.i("history", "--------once history finish--------- ");
    }

MotionEvent数据获取

MotionEvent中提供很多方法来获取event相关属性,如坐标、压力信息等。但是MotionEvent类中大多数方法接受的是event的index,而不是id。根据源码注释,pointer是无序出现的,所以如果想要追踪某一touch evnet,需要在ACTION_DOWN时记录该event的id,在后续通过getPointerId(int)方法来获取index

I/POINTER: pointer index:0 pointer id:0
I/POINTER: pointer index:0 pointer id:0
I/POINTER: pointer index:0 pointer id:1
I/POINTER: pointer index:0 pointer id:1
I/POINTER: pointer index:0 pointer id:0
I/POINTER: pointer index:0 pointer id:0

TouchEvent事件分发一致性

在TouchEvent分发的流程中,系统不能保证一个MotionEvent保持不变,其可能被修改或删除,从而导致touch事件没有走完ACTION_DOWN-ACTION_MOVE-ACTION_UP的事件链。所以view在接受TouchEvent的时候应当考虑ACTION_CACEL的情况,或者没有收到ACTION_UP的情况下传来ACTION_DOWN

参考

触摸事件【MotionEvent】简介

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值