Android触摸事件传递机制小记
来源:互联网 发布:php官方文档 编辑:程序博客网 时间:2024/06/03 21:52
- 事件类型
- API
- 事件流程
- 事件处理
事件类型
我们可以通过event.getAction()方法来获得Action的状态值。
API
事件流程
为了方便演示实现建好了几个类 //部分代码省略
- MainActivity
- ViewGroupOne
- ViewGroupTwo
- TestView
public class MainActivity extends AppCompatActivity { public static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView testView= (TextView) findViewById(R.id.testview); testView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "testview", Toast.LENGTH_SHORT).show(); } }); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouchEvent--->ACTION_UP"); break; } return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent--->ACTION_UP"); break; }// return true; return super.dispatchTouchEvent(ev); }
public class ViewGroupOne extends RelativeLayout { public static final String TAG = "ViewGroupOne"; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent--->ACTION_UP"); break; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouchEvent--->ACTION_UP"); break; } return super.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onInterceptTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onInterceptTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onInterceptTouchEvent--->ACTION_UP"); break; } return super.onInterceptTouchEvent(ev); }}
public class ViewGroupTwo extends RelativeLayout { public static final String TAG = "ViewGroupTwo"; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent--->ACTION_UP"); break; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouchEvent--->ACTION_UP"); break; } return super.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onInterceptTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onInterceptTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onInterceptTouchEvent--->ACTION_UP"); break; } return super.onInterceptTouchEvent(ev); }
public class TestView extends TextView { public static final String TAG = "TestView"; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent--->ACTION_DOWN"); getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent--->ACTION_UP"); break; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onTouchEvent--->ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouchEvent--->ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouchEvent--->ACTION_UP"); break; } return super.onTouchEvent(event); }}
上图1区域代表ViewGroupOne,2区域代表ViewGroupTwo ,TextView代表TestView
关系为One include Two include test
- 不做任何处理
//触摸1E/MainActivity: dispatchTouchEvent--->ACTION_DOWNE/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWNE/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWNE/ViewGroupOne: onTouchEvent--->ACTION_DOWNE/MainActivity: onTouchEvent--->ACTION_DOWNE/MainActivity: dispatchTouchEvent--->ACTION_MOVEE/MainActivity: onTouchEvent--->ACTION_MOVEE/MainActivity: dispatchTouchEvent--->ACTION_MOVEE/MainActivity: onTouchEvent--->ACTION_MOVEE/MainActivity: dispatchTouchEvent--->ACTION_UPE/MainActivity: onTouchEvent--->ACTION_UP//触摸2E/MainActivity: dispatchTouchEvent--->ACTION_DOWNE/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWNE/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWNE/ViewGroupTwo: dispatchTouchEvent--->ACTION_DOWNE/ViewGroupTwo: onInterceptTouchEvent--->ACTION_DOWNE/ViewGroupTwo: onTouchEvent--->ACTION_DOWNE/ViewGroupOne: onTouchEvent--->ACTION_DOWNE/MainActivity: onTouchEvent--->ACTION_DOWNE/MainActivity: dispatchTouchEvent--->ACTION_MOVEE/MainActivity: onTouchEvent--->ACTION_MOVEE/MainActivity: dispatchTouchEvent--->ACTION_MOVEE/MainActivity: onTouchEvent--->ACTION_MOVEE/MainActivity: dispatchTouchEvent--->ACTION_UPE/MainActivity: onTouchEvent--->ACTION_UP//触摸TextView(设置了点击事件) E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWN E/ViewGroupTwo: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupTwo: onInterceptTouchEvent--->ACTION_DOWN E/TestView: dispatchTouchEvent--->ACTION_DOWN E/TestView: onTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupTwo: dispatchTouchEvent--->ACTION_MOVE E/TestView: dispatchTouchEvent--->ACTION_MOVE E/TestView: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupTwo: dispatchTouchEvent--->ACTION_MOVE E/TestView: dispatchTouchEvent--->ACTION_MOVE E/TestView: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupTwo: dispatchTouchEvent--->ACTION_MOVE E/TestView: dispatchTouchEvent--->ACTION_MOVE E/TestView: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupTwo: dispatchTouchEvent--->ACTION_MOVE E/TestView: dispatchTouchEvent--->ACTION_MOVE E/TestView: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP E/ViewGroupOne: dispatchTouchEvent--->ACTION_UP E/ViewGroupTwo: dispatchTouchEvent--->ACTION_UP E/TestView: dispatchTouchEvent--->ACTION_UP E/TestView: onTouchEvent--->ACTION_UPSo :在正常情况下 1.传递的顺序为dispatchTouchEvent--->onInterceptTouchEvent--->onTouchEvent 2.分发的层级为Activity--->ViewGroupOne--->ViewGroupTwo (从外向内) 3.分发事件类型的顺序为Down--->Move--->up 4.若下级视图没有消费事件,最终返回到最上层处理,若被消费则不返回上层
- 处理分发
return true;//return super.dispatchTouchEvent(ev);1.当MainActivity dispatchTouchEvent返回true 无论触摸任何区域 E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP2.当ViewGroupOne dispatchTouchEvent返回true 无论触摸任何区域 E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP E/ViewGroupOne: dispatchTouchEvent--->ACTION_UP3.当TestView dispatchTouchEvent返回true 触摸TextView(不会弹出土司) E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWN E/ViewGroupTwo: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupTwo: onInterceptTouchEvent--->ACTION_DOWN E/TestView: dispatchTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupOne: dispatchTouchEvent--->ACTION_MOVE E/ViewGroupTwo: dispatchTouchEvent--->ACTION_MOVE E/TestView: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP E/ViewGroupOne: dispatchTouchEvent--->ACTION_UP E/ViewGroupTwo: dispatchTouchEvent--->ACTION_UP E/TestView: dispatchTouchEvent--->ACTION_UP 触摸区域1 E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWN E/ViewGroupOne: onTouchEvent--->ACTION_DOWN E/MainActivity: onTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP E/MainActivity: onTouchEvent--->ACTION_UPSo:得出的结论是 1.当dispatchTouchEvent 返回true的时候不会往下执行任何事件(因为最先调用分发) 2.当这个层级的dispatchTouchEvent 返回true的时候 如果点击到本层级或者下层级,不会执行onTouchEvent,上层级正常
- 处理拦截
ViewGroup作为容器,它有特有的一个方法,onInterceptTouchEvent,顾名思义,这个方法可以拦截容器内的层级执行
return true;//return super.onInterceptTouchEvent(ev); 将ViewGroupOne返回true//触摸任何区域 E/MainActivity: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: dispatchTouchEvent--->ACTION_DOWN E/ViewGroupOne: onInterceptTouchEvent--->ACTION_DOWN E/ViewGroupOne: onTouchEvent--->ACTION_DOWN E/MainActivity: onTouchEvent--->ACTION_DOWN E/MainActivity: dispatchTouchEvent--->ACTION_MOVE E/MainActivity: onTouchEvent--->ACTION_MOVE E/MainActivity: dispatchTouchEvent--->ACTION_UP E/MainActivity: onTouchEvent--->ACTION_UPSo:一切正常,只是不会在传递到下层
Ps:既然上层有拦截,那么下层就会有反拦截,这个方法为getParent().requestDisallowInterceptTouchEvent(boolean disallowIntercept);但是有的童鞋反应改该方法无效,其实这是因为调用时机不对,例如:
1.所有事件返回true,反拦截无效(因为根本没机会进入你下层的触摸事件)2.假设ViewGroupOne 的onInterceptTouchEvent这样写 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "onInterceptTouchEvent--->ACTION_DOWN"); return false; //这里有机会进入下层 case MotionEvent.ACTION_MOVE: Log.e(TAG, "onInterceptTouchEvent--->ACTION_MOVE"); return true; case MotionEvent.ACTION_UP: Log.e(TAG, "onInterceptTouchEvent--->ACTION_UP"); return false; } return super.onInterceptTouchEvent(ev); }而TestView 的dispatchTouchEvent或者onTouchEvent 这样写 @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "dispatchTouchEvent--->ACTION_DOWN"); //getParent().requestDisallowInterceptTouchEvent(true); //只有这里才好使,正常弹出土司(上层进入调用反拦截) break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "dispatchTouchEvent--->ACTION_MOVE"); //getParent().requestDisallowInterceptTouchEvent(true); //上层已经拦截,进不来 break; case MotionEvent.ACTION_UP: Log.e(TAG, "dispatchTouchEvent--->ACTION_UP"); //getParent().requestDisallowInterceptTouchEvent(true); break; } return super.dispatchTouchEvent(ev); }
如果有错误请大家指出 反正我也不会改的 ~(≧▽≦)/~
开玩笑 (ฅ>ω<*ฅ)
阅读全文
0 0
- Android触摸事件传递机制小记
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- android 触摸事件传递机制
- android触摸事件传递机制
- Android 触摸事件传递机制
- Android触摸事件传递机制
- Android触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- 关于android触摸事件传递机制
- Android View 触摸事件传递机制
- Android ViewGroup 触摸事件传递机制
- Android触摸事件传递机制学习笔记
- 【学习摘记】马士兵bbs改良版_课时36_修改
- hdu6216 A Cubic number and A Cubic Number
- 链表翻转
- android如何扫描歌曲 信息
- 使用Redis SETNX 命令实现分布式锁
- Android触摸事件传递机制小记
- linux 僵尸进程defunct ps auxf
- eclipse中使用git
- python学习笔记--random模块
- 数据库---关系代数
- maven的web项目启动时找不到ContextLoaderListener
- EntityFrameWork数据迁移——暨改变数据库结构的方法
- Spring加载配置文件流程
- Tomcat 部署异常搜集