Android MotionEvent中getX()与getRawX()都是获取屏幕坐标(横),但二者又有区别 getX() : 是获取相对当前控件(View)的坐标 findViewById(R.id.btn); btn.setOnTouchListener(this); } @Override public boolean onTouch(View view, MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN : break; case MotionEvent.ACTION_MOVE: x = (int) event.getX(); y = (int) event.getY(); "homer", "x = " + x + "; y = " + y + "; rawX = " + rawX + "; rawY = " + rawY); break; case MotionEvent.ACTION_UP
MotionEvent 触摸动作触发的输入事件由MotionEvent表示,它实现了Parcelable接口——IPC需求。 目前的设备几乎都支持多点触摸,每个触摸中的手指被当做一个poiner。 相比上一个MotionEvent数据,当前MotionEvent的所有数据都是最新的。打包的数据根据时间形成数组,而最新的数据被作为current数据。 下面是获得当前MotionEvent中所有事件的各个poiner的坐标的标准形式: void printSamples(MotionEvent ev) { final int historySize : return "Down"; case MotionEvent.ACTION_MOVE: return "Move"; case MotionEvent.ACTION_POINTER_DOWN : return "Pointer Down"; case MotionEvent.ACTION_UP: return "Up"; case MotionEvent.ACTION_POINTER_UP
MotionEvent在android的触摸事件中起到了很重要的作用,本文主要介绍MotionEvent,简要介绍触摸事件,主要包括 单点触控、多点触控、鼠标事件 以及 getAction() 和 getActionMasked Android 将所有的输入事件都放在了 MotionEvent 中: 版本号 更新内容 Android 1.0 (API 1 ) 支持单点触控和轨迹球的事件。 switch (event.getAction()){ case MotionEvent.ACTION_DOWN: // 手指按下 break; case MotionEvent.ACTION_MOVE: // 手指移动 break; case MotionEvent.ACTION_UP 3、这些事件不会传递到 onTouchEvent(MotionEvent) 而是传递到 onGenericMotionEvent(MotionEvent) 。
class MainActivity extends AppCompatActivity { @Override public boolean dispatchTouchEvent(MotionEvent { return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent * * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent
用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY 用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, 用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY
(MotionEvent event) 3、 public boolean onInterceptTouchEvent(MotionEvent event) 在View和ViewGroup 接下来就是这些方法的参数,都接受了一个MotionEvent类型的参数,MotionEvent继承于InputEvent,用于标记各种动作事件。 1、无子控件情况 新建一个工程,在MainActivity里面重写dispatchTouchEvent(MotionEvent ev)以及onTouchEvent(MotionEvent event : Log. i("MainActivity--onTouchEvent", "MotionEvent.ACTION_MOVE" ); break; case MotionEvent.ACTION_UP ", "MotionEvent.ACTION_MOVE" ); break; case MotionEvent.ACTION_UP: Log. i("MainActivity--onTouch", "MotionEvent.ACTION_UP
(MotionEvent e); boolean onSingleTapUp(MotionEvent e); boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY); void onLongPress(MotionEvent e); boolean onFling(MotionEvent (MotionEvent e); } public interface OnContextClickListener { boolean onContextClick(MotionEvent 注意:onDoubleTap传入的参数MotionEvent是第一次点击时的DOWN事件,且onDoubleTap只会在此处被调用一次;onDoubleTapEvent()传入的参数MotionEvent e1, MotionEvent e2, float distanceX, float distanceY),其中e1是DOWN事件的Motionevent ,e2是MOVE事件的MotionEvent
事件分发的对象是谁 系统把事件封装为MotionEvent对象,事件分发的过程就是MotionEvent分发的过程。 >DecorView -> ViewGroup ->View 主要传递对象及顺序 Activity 、 ViewGroup、 View Activity中 dispatchTouchEvent(MotionEvent ev) onTouchEvent(MotionEvent event) ViewGroup中 dispatchTouchEvent(MotionEvent ev) onInterceptTouchEvent (MotionEvent ev) onTouchEvent(MotionEvent event) View中 dispatchTouchEvent(MotionEvent ev) onTouchEvent (MotionEvent event) 验证 (事件传递流程) 代码测试 MainActivity public class MainActivity extends AppCompatActivity
1 ViewGroup(比如LinearLayout) 2 boolean dispatchTouchEvent(MotionEvent event) 3 boolean onInterceptTouchEvent (MotionEvent event) 4 boolean onTouchEvent(MotionEvent event) 5 6 View(比如Button) 7 boolean dispatchTouchEvent (MotionEvent event) 8 boolean onTouchEvent(MotionEvent event) 总的来说,dispatchTouchEvent决定处理什么,onInterceptTouchEvent event){ 15 if(MotionEvent.ACTION_DOWN == event.getAction()){ 16 Log.v(TAG + "dispatchTouchEvent:", @Override 02 public boolean dispatchTouchEvent(MotionEvent event){ 03 if(MotionEvent.ACTION_DOWN =
(强调还未移动或者松开),对应动作:MotionEvent.ACTION_DOWN public void onShowPress(MotionEvent e) { } // 控件单击时候调用的方法,对应动作:MotionEvent.ACTION_DOWN ---> MotionEvent.ACTION_UP public boolean ,对应动作:MotionEvent.ACTION_DOWN ---> MotionEvent.ACTION_MOVE(多个) * 方法中四个参数的含义:e1:第一次调用 onScroll */ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
方法就行: float latestX; float latestY; @Override public boolean onInterceptTouchEvent(MotionEvent : isIntercept = false; break; case MotionEvent.ACTION_MOVE ev) { boolean isIntercept = false; if (ev.getAction() == MotionEvent.ACTION_DOWN) { ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: getParent ().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE
重写View的onTouchEvent()方法,传递进来MotionEvent对象 调用MotionEvent对象的getAction()方法,获取当前动作 switch判断一下当前动作 事件为MotionEvent.ACTION_DOWN 是手指第一次触摸屏幕 事件为MotionEvent.ACTION_MOVE是手指在屏幕上移动 事件为MotionEvent.ACTION_UP是手指离开屏幕 当手指触摸到屏幕 定义手指最后的坐标lastX 调用MotionEvent对象的getX() 方法,得到lastX的值 当手指在屏幕上移动 定义手指横向移动的距离dis 调用getX()-lastX就是移动的距离 定义滑动按钮的左边就是这个移动的距离 android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent ; /** * 触摸事件 */ private int firstX; @Override public boolean onTouchEvent(MotionEvent
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent ; public class Util { public static String getActionString(MotionEvent ev){ String action = ""; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: action = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: action = "ACTION_MOVE "; break; case MotionEvent.ACTION_UP: action = "ACTION_UP";
用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY 用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, 用户按下触摸屏 & 拖动 public boolean onScroll(MotionEvent e1, MotionEvent e2, onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY
首先,对于 ViewGroup 来说,我们可以选择性的重写下面三个方法: public boolean dispatchTouchEvent(MotionEvent ev); public boolean onInterceptTouchEvent(MotionEvent ev); public boolean onTouchEvent(MotionEvent ev); 我们分别来看一下这三个方法: ? (MotionEvent ev) { return onTouchEvent(ev); } 接下来要明白: 1、无论是对于 View 还是 ViewGroup来说,一个 触摸事件(MotionEvent 对象) 只要能传递给这个 View/ViewGroup , 那么这个 View/ViewGroup 的 dispatchTouchEvent(MotionEvent event) 就一定会被调用 2 所以之前只有一遍 LogCat ,即只有 ACTION_DOWN 类型的 MotionEvent 对象被传递了,ACTION_UP 类型的 MotionEvent 对象并没有传递给这个 View 处理。
所谓点击事件(Touch)的事件分发,其实就是对MotionEvent(Touch的封装)事件的分发过程,即当一个MotionEvent产生以后,系统需要把这这个事件传递给那个具体的View。 1.MotionEvent 那么MotionEvent又是什么呢? 这个类就是记录手指接触屏幕后所产生的一系列的事件(也就是说我们事件分发其实就是分发MotionEvent这个对象)。 事件的类型与含义如下: 事件类型 具体动作 MotionEvent.ACTION_DOWN 按下View(所有事件的开始) MotionEvent.ACTION_UP 抬起View(与DOWN对应) MotionEvent.ACTION_MOVE 当接收到MotionEvent.ACTION_UP是。 当接收到MotionEvent.ACTION_UP时(前提MotionEvent.ACTION_DOWN也接收到了)会经过判断最后执行 performClick();方法。
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; (MotionEvent e) { return false; } } main.xml <? e):down事件,表示按下事件 2、onSingleTapUp(MotionEvent e):一次点击up事件,表示按下后的抬起事件 3、onShowPress(MotionEvent e):down (由系统分配,也可自定义),如果仍然按住屏幕则视为长按事件 5、onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY ):滑动手势事件,例如scroll事件后突然up,fling的速度大小由e每秒x和y改变大小决定 6、onScroll(MotionEvent e1, MotionEvent e2, float distanceX
GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Toast.makeText(MainActivity.this e1, MotionEvent e2, float velocityX, float velocityY) { Toast.makeText(MainActivity.this e) { return false; } @Override public boolean onDoubleTap(MotionEvent e) { return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { return
下面是去年我写代码的时候,自定义长按事件的方式: package chroya.fun; import android.content.Context; import android.view.MotionEvent isReleased || isMoved) return; performLongClick(); } }; } public boolean dispatchTouchEvent(MotionEvent int x = (int) event.getX(); int y = (int) event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN 下面讲讲第二种方式: package chroya.fun; import android.content.Context; import android.view.MotionEvent; import public void run() { performLongClick(); } }; } public boolean dispatchTouchEvent(MotionEvent
GestureDetector.OnGestureListener 监听类中有六个函数要重写: OnDown(MotionEvent e) 用户按下屏幕就会触发; onShowPress(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) 滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发 参数解释: e1:第1个ACTION_DOWN MotionEvent e2:最后一个ACTION_MOVE MotionEvent velocityX:X轴上的移动速度,像素/秒 velocityY:Y轴上的移动速度,像素/秒 onScroll(MotionEvent e1, MotionEvent e2,float distanceX 触发顺序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed onDoubleTap(MotionEvent e) 双击事件 onDoubleTapEvent(MotionEvent