Android 事件分发机制
来源:互联网 发布:皇家骑士团java 编辑:程序博客网 时间:2024/05/16 12:47
简介
- Android 事件分发机制是Android UI非常重要的一个机制,处理UI逻辑的时候必须要非常清楚事件分发的顺序。 这里以TouchEvent事件来举例子。
- TouchEvent事件从Activity开始分发然后分发到布局文件的各个View中。
Activity,View,ViewGroup中TouchEvent的处理方法
- Activity 中TouchEvent的处理方法
dispatchTouchEvent(MotionEvent ev)
onTouchEvent(MotionEvent event) - ViewGroup中TouchEvent的处理方法
dispatchTouchEvent(MotionEvent ev)
onInterceptTouchEvent(MotionEvent ev)—-默认返回false
onTouchEvent(MotionEvent event) - View中TouchEvent的处理方法
dispatchTouchEvent(MotionEvent ev)
onTouchEvent(MotionEvent event)
那么TouchEvent 就在以上的几个类中分发了,根据不同方法的返回值作不同的分发处理。
返回true-消费这个事件。
返回false-分发这个事件。
Activity,ViewGroup,View中TouchEvent分发示例
- 一个Activity,该Activity包含一个布局文件,该布局文件包含两个自定义的View,第一个view继承LinearLayout,第二个view继承View。
- 在这里每一个view的dispatchTouchEvent和onTouchEvent方法都必须调用父类的dispatchTouchEvent和onTouchEvent的方法,这样事件才会一层一层的分发下去,如果不重写,dispatchTouchEvent或者onTouchEvent直接返回true或者false,事件到当前view就不会再分发给子view。
布局关系图
实现Activity 中事件处理的方法。
public class TestEventActivity extends AppCompatActivity { static final String TAG = "TestEvent-"+TestEventActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test_event); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar) } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG,"onTouchEvent"); return super.onTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG,"dispatchTouchEvent"); return super.dispatchTouchEvent(ev); }}
实现ViewGroup 中事件处理的方法
public class FirstView extends LinearLayout { static final String TAG = "TestEvent-"+FirstView.class.getSimpleName(); public FirstView(Context context) { super(context); } public FirstView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG,"dispatchTouchEvent false"); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d(TAG,"onInterceptTouchEvent false"); return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG,"onTouchEvent false"); return super.onTouchEvent(event); }}
实现View 中事件处理的方法
public class SecondView extends View { static final String TAG = "TestEvent-"+ThirdView.class.getSimpleName(); public ThirdView(Context context) { super(context); } public ThirdView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG,"dispatchTouchEvent"); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG,"onTouchEvent"); return super.onTouchEvent(event); }}
默认情况下TouchEvent 事件的分发流程.所有的事件处理方法都返回false,
D/TestEvent-TestEventActivity: dispatchTouchEvent ACTION_DOWND/TestEvent-FirstView: dispatchTouchEvent ACTION_DOWND/TestEvent-FirstView: onInterceptTouchEvent ACTION_DOWND/TestEvent-SecondView: dispatchTouchEvent ACTION_DOWND/TestEvent-SecondView: onTouchEvent ACTION_DOWND/TestEvent-FirstView: onTouchEvent ACTION_DOWND/TestEvent-TestEventActivity: onTouchEvent ACTION_DOWND/TestEvent-TestEventActivity: dispatchTouchEvent ACTION_MOVED/TestEvent-TestEventActivity: onTouchEvent ACTION_MOVED/TestEvent-TestEventActivity: dispatchTouchEvent ACTION_UPD/TestEvent-TestEventActivity: onTouchEvent ACTION_UP
ACTION_DOWN事件通过dispatchTouchEvent传递顺序
ACTION_DOWN事件通过onTouchEvent传递顺序
- ACTION_DOWN事件通过dispatchTouchEvent 的分发顺序是从Activity开始的,通过onTouchEvent的分发顺序是从SecondView开始的。
- 因为FirstView和SecondView事件处理方法都返回false,后续的ACTION_MOVE,ACTION_UP事件也不会再分发下去,到Activity就终止了。
从上面的结论可以看出,默认情况下系统先按照UI布局的结构从外到里通过调用各个组件的dispatchTouchEvent方法来传递事件,然后再从里到外通过调用各个组件的onTouchEvent方法传递事件,这样一个循环的模式。在调用的过程当中,只要有方法返回true就表示事件被消费了,事件将不会再分发下去。
Activity的dispatchTouchEvent 返回true
*ACTION_DOWN*事件分发顺序还是和上面两个图一样,但是后续的*ACTION_MOVE,ACTION_UP*只会在Activity消费了。
FirstView的dispatchTouchEvent或者onTouchEvent方法返回true
dispatchTouchEvent传递*ACTION_DOWN*事件还是和上图一样。但是onTouchEvent传递*ACTION_DOWN*事件就不一样了,到FirstView就不会再往下传递了,dispatchTouchEvent方法和onTouchEvent传递*ACTION_MOVE,ACTION_UP*也一样,到了FirstView就会被拦截消费。
SecondView的dispatchTouchEvent或者onTouchEvent方法返回true
dispatchTouchEvent传递*ACTION_DOWN,ACTION_MOVE,ACTION_UP*事件还是和上图一样。但是onTouchEvent传递*ACTION_DOWN,ACTION_MOVE,ACTION_UP*事件就不一样了,到SecondView就不会再往下传递了。
1 1
- android事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android 事件分发机制
- Android 事件分发机制
- android 事件分发机制
- Android事件分发机制
- android 事件分发机制
- android事件分发机制
- Android 事件分发机制
- android事件分发机制
- android 事件分发机制
- android 事件分发机制
- Android 事件分发机制
- Android事件分发机制
- Android事件分发机制
- Android 事件分发机制
- SQL Server数据库技术WEEK2-1
- Webstorm/Phpstorm设置FTP
- WINDOWS下双网卡做负载均衡(转载内容)
- Troubleshooting Device and Driver Installations
- tomcat默认访问的项目(域名直接访问项目,不带端口)
- Android 事件分发机制
- uboot环境变量
- WebDriver API详解-操作浏览器
- iptables的九个使用实例
- 食品添加剂,酪蛋白酸钠,单硬脂酸甘油酯,蔗糖脂肪酸酯
- 每天一个linux命令(10):cat 命令
- linux 中cut命令
- 什么是步进电机的细分? 什么是细分?是不是细分越高精度越高?
- 历遍指定文件夹下的文件