Android 事件分发介绍
来源:互联网 发布:北京python工程师工资 编辑:程序博客网 时间:2024/05/20 09:05
事件分发所解决的问题:
onTouch和onTouchEvent有什么区别,又该如何使用?
为什么给ListView引入了一个滑动菜单的功能,ListView就不能滚动了?
ListView的Item中有Button,onItemClick为什么会失效?
等。。。
什么是事件分发:
事件分发就是当用户点击了屏幕,那么就触发了一个事件event,而这个事件在每一层的传递与分发过程就叫做事件分发。
三个主要的方法:
dispatchTouchEvent接收事件、onTouchEvent消费事件 (这两个方法存在view中);
onInterceptTouchEvent截断事件并交给onTouchEvent处理掉(这个方法存在viewGroup)。
分发过程:
只要你触摸到了一个控件,那么事件主要按照activity→viewgroup→view的顺序传递,
(这里并不是准确的顺序,所谓主要就是我们一般只会在这三个层面对事件分发过程进行介入与及操作)
首先在activity中执行dispatchTouchEvent接收事件,activity不存在onInterceptTouchEvent方法,
所以不能截断事件,当然也不能执行截断事件后的onTouchEvent,这时候activity就把事件传递给了
viewgroup的dispatchTouchEvent,viewgroup默认onInterceptTouchEvent为false即不拦截,直接把
事件传递给了view的dispatchTouchEvent,view接收到这个事件因为没onInterceptTouchEvent不能
截断并且处于最下层已经不能再往下传了,所以只能执行onTouchEvent消费了这个事件,但是在这之前
他会判断这个view是否符合三个条件:
1,控件注册了setOnTouchListener事件
2,控件的enable为true
3,onTouch方法里返回true
满足以上三个条件执行完onTouch后dispatchTouchEvent方法返回true,传递结束,否则返回false,事件传递给控件的onclick和onTouchEvent(TextView的click默认返回为false,Button,checkBox默认返回为true)
onTouchEvent返回为false的话则把事件传递给与其父view的onTouch,以此类推
结论:
(所以以上流程任一项返回了true,则事件终止传递,自定义一个layout重写以上任意方法返回true亦会终止。)
下面是一个activity复写dispatchTouchEvent方法拦截点击事件,隐藏输入法的例子:
//这个方法判断是否点击了editText外部
public static boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] leftTop = { 0, 0 };
v.getLocationInWindow(leftTop);
int left = leftTop[0], top = leftTop[1], bottom = top
+ v.getHeight(), right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
return false;
} else {
return true;
}
}
return false;
}
//这个方法用于隐藏输入法
public static Boolean hideInputMethod(Context context, View v) {
InputMethodManager imm = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
return imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (HideInput.isShouldHideInput(v, ev)) {
if(HideInput.hideInputMethod(this, v)) {
return true; //返回true,拦截事件,其他控件不响应,注释则不拦截点击事件。
}
}
}
return super.dispatchTouchEvent(ev);
}
- Android 事件分发介绍
- Android事件分发详细介绍
- Android之---事件分发机制详细介绍
- android 点击事件分发简单介绍
- 总结的不错的Android事件分发介绍
- android中的事件分发与消费机制简答介绍
- android事件分发
- android 事件分发
- android事件分发
- android事件分发机制
- Android 事件分发
- Android事件分发机制
- Android 事件分发机制
- Android事件分发机制
- android事件分发
- Android事件的分发
- Android 事件分发机制
- android事件的分发
- Can't connect to local MySQL server through socket '/tmp/mysql.sock'错误
- Socket传输序列化对象
- StackView堆叠视图
- RSA加密算法操作的java演示
- leetcode笔记:Jump Game II
- Android 事件分发介绍
- php之与python进行socket通信
- AdapterViewFlipper自动播放图片
- 内排序-数组实现(c++)
- 公开的海量数据集 Public Research-Quality Datasets
- 关于Android沉浸式通知栏的一个开源库SystemBarTint简单使用
- 自动完成文本框
- 区间覆盖问题(贪心)
- 使用s 搭建项目 报异常 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException