Android事件分发
这里我参考了@Hensen_的事件分发博文,不会没关系,想深入了解可以点链接学习。我主要简单的说一下结论。我们知道事件分发有三个方法dispatchTouchEvent,onInterceptTouchEvent和onTouchEvent ,这三个方法是事件传递的不同过程,我们关注的是怎么通过事件分发获取手指在屏幕上的动作。
Android View.OnTouchListener
这个方法可以获取当前View里的点击的事件,我们可以通过这个接口来获取当前View的手势信息。
MotionEvent
附上Google官方文档:MotionEvent
我们重写以上三个方法时会发现它传入的参数是MotionEvent,其实通过这个参数就可以获取我们需要的手势信息,下面是几个重要的方法。
返回值 | 方法 | 描述 |
---|---|---|
long | getDownTime() | Returns the time (in ms) when the user originally pressed down to start a stream of position events. |
- | - | 返回一系列操作的时间 |
long | getEventTime() | Retrieve the time this event occurred, in the SystemClock.uptimeMillis() time base. |
- | - | 返回事件发生的时间点 |
int | getAction() | Return the kind of action being performed. |
- | - | 返回事件的类型 |
float | getRawX() | Returns the original raw X coordinate of this event. |
- | - | 返回以屏幕左上角为原点时的X值 |
float | getRawY() | Returns the original raw Y coordinate of this event. |
- | - | 同上 |
float | getX() | getX(int) for the first pointer index (may be an arbitrary pointer identifier). |
- | - | 以控件左上角为原点时的X值 |
float | getY() | getY(int) for the first pointer index (may be an arbitrary pointer identifier). |
- | - | 同上 |
方法中有一个getAction(),这个方法就可以判断用户在屏幕上做的手势。一般常用的几个方法有ACTION_MOVE,ACTION_DOWN,ACTION_UP,顾名思义他们分别监听滑动,按下和抬起三个手势。有的View需要设置clickable = “ture” 才能捕获移动和抬起事件 。我们需要记录手势信息,这些还是远远不够的,我们还需要获取手势持续的时间,这里有两个思路:
1.通过记录ACTION_DOWN和ACTION_UP的时间点做差
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
dateStart = date.getTime();
break;
case MotionEvent.ACTION_UP:
dateEnd = date.getTime();
during = dateEnd - dateStart;
Log.d(TAG, "onTouch: during:" + during);
break;
}
我们通过做差的方式可以获取我们手势的持续时间,需要注意的是dateStart和dateEnd需要定义在方法外面,不然方法被掉用后就会重置之前记录的数值。
2.通过记录每一段手势的信息求和,这个有需要再探究。
获取和存贮手势信息
获取到了手势信息,我们就需要把它存下来可以用来传输或者记录下来做成脚本。这里我们可以用一个二维数组来存储手势,再自定义一个类来存储详细信息
public class OperationModel {
private int durationTime;
private int delayTime;
private List list;
}
这里的durationTime就是我们定义手势的持续时间,list用来存储手势。这里的List其实是一个点的类的ArrayList。
public boolean onTouch(View view, MotionEvent motionEvent) {
Date date = new Date();
if (view.getId() == R.id.sf) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (list.size() != 0)
list.clear();
if (operationModel!=null) {
operationModel.clear();
operationModel = null;
}
dateStart = date.getTime();
locationModel = new LocationModel((int)motionEvent.getX(),(int)motionEvent.getY());
list.add(locationModel);
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "onTouchEvent: getAction:" + motionEvent.getAction());
Log.d(TAG, "onTouchEvent: getX:" + motionEvent.getX());
Log.d(TAG, "onTouchEvent: getY:" + motionEvent.getY());
locationModel = new LocationModel((int)motionEvent.getX(),(int)motionEvent.getY());
list.add(locationModel);
case MotionEvent.ACTION_UP:
dateEnd = date.getTime();
during = dateEnd - dateStart;
locationModel = new LocationModel((int)motionEvent.getX(),(int)motionEvent.getY());
list.add(locationModel);
operationModel = new OperationModel();
operationModel.setDelayTime(0);
operationModel.setDurationTime((int)during);
operationModel.setList(list);
Log.d(TAG, "onTouch: during:" + during);
break;
}
}
return false;
}
我们定义了一个点的类,和一个手势类,然后根据不同手势类型方法的过程,拼装手势信息,这里就不多说了,自己多看一下就能看懂。这样我们就可以把手势信息存储下来了。好了大功告成!!!
总结一下:
1.通过重新控件的分发方法或者onTouchListener为切入点
2.通过对不同MotionEvent的监听并用getX()和getY()方法获取点和时间信息
3.对点的信息进行封装,得到手势信息