博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android_事件分发机制_几行代码直接通晓
阅读量:4290 次
发布时间:2019-05-27

本文共 2277 字,大约阅读时间需要 7 分钟。

/**
 * View的事件分发
 */
public class View{
public boolean dispatchTouchEvent(MotionEvent ev){
boolean result = false;
// 先判断是否设置了onTouchListener,如果设置了,就调用
if (mOnTouchListener != null && mOnTouchListener.onTouch(ev)) {
result = true;
}
// 如果没有设置onTouchListener,或者调用了onTouch后返回了false,那么就调用onTouchEvent
if (!result && onTouchEvent(ev)) {
result = true;
}
return result;
}
public boolean onTouchEvent(MotionEvent ev){
// 如果View可点击
if (isClickable()) {
switch (ev.getAction()) {
...
case MotionEvent.ACTION_UP:
...
// 判断是否设置了onClickListener,设置了就调用,并消耗事件
if (mOnClickListener != null) {
mOnClickListener.onClick(this);
}
...
break;
...
}
// 可点击的View,默认会消耗掉事件
return true;
}
// 不可点击的View,默认不消耗事件
return false;
}
}
/**
 * ViewGroup的事件分发
 */
public class ViewGroup extends View{
// 一旦有子元素消耗了事件,这个子元素就被赋值给mFirstTouchTarget
public View mFirstTouchTarget = null;
public boolean dispatchTouchEvent(MotionEvent ev){
int action = ev.getAction();
boolean handled = false;
boolean intercepted;
// DOWN事件,或者有子元素消耗事件,则进入if语句内,判断是否拦截
if (action == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
// 取出 是否允许拦截 的标记,默认是false。子元素可以通过requestDisallowInterceptTouchEvent(true);将这个标记设置为true
boolean disallow = getFlagDisallowIntercept();
if (!disallow) {
// 允许拦截,调用onInterceptTouchEvent判断是否拦截
intercepted = onInterceptTouchEvent(ev);
}else {
// 不允许拦截,直接不拦截
intercepted = false;
}
}else {
// 非DOWN事件,或者没有子元素消耗了事件,直接拦截
intercepted = true;
}
// 如果有子元素消耗事件,alreadyDispatched就被赋值为true
boolean alreadyDispatched = false;
if (!intercepted) {
// 不拦截事件
// 遍历子元素
for (int i = 0 ; i < mChildList().size() ; i++) {
View child = mChildList.get(i);
float x = ev.getX();
float y = ev.getY();
if (x >= child.left && x <= child.right && y >= child.top && y <= child.bottom) {
// 事件位于子元素所在区域内,将事件分发给子元素
if (child.dispatchTouchEvent(ev)) {
// 子元素消耗了事件
mFirstTouchTarget = child;
alreadyDispatched = true;
// 跳出循环,不再分发
break;
}
}
}
}
if (mFirstTouchTarget == null) {
// 没有子元素消耗事件
// ViewGroup自行处理事件
super.dispatchTouchEvent(ev);
}else {
// 有子元素消耗了事件,则后续事件全部交给该子元素处理,不管他是否消耗事件
if (alreadyDispatched) {
mFirstTouchTarget.dispatchTouchEvent(ev);
handled = true;
}
}
return handled;
}
public boolean onTouchEvent(MotionEvent ev){
super.onTouchEvent(ev);
}
public boolean onInterceptTouchEvent(MotionEvent ev){
return false;
}
}

转载地址:http://udegi.baihongyu.com/

你可能感兴趣的文章
Linux 互斥锁、原子操作实现原理
查看>>
搭建简单hls直播测试服务
查看>>
共享内存的数据同步
查看>>
Cache和Buffer的区别
查看>>
50个sql语句
查看>>
MYSQL sql 语句性能分析
查看>>
C++操作Redis数据库
查看>>
python yield用法
查看>>
python pipe模块用法
查看>>
安装完 MySQL 后必须调整的 10 项配置
查看>>
开发者必备的 12 个 JavaScript 库
查看>>
http错误码
查看>>
python 多线程
查看>>
sipp命令 各参数含义
查看>>
搜集的动植物分类、检索网站
查看>>
ffmpeg源码分析之媒体打开过程
查看>>
Ubuntu/centos/redhat/SUSE sipp安装(带rtp支持,3.5.1版本)
查看>>
周鸿祎:很多程序员聪明,但我一看就知道他不会成功
查看>>
编译程序遇到问题 relocation R_X86_64_32 against `.rodata' can not be used when making a shared object;
查看>>
Const指针 、 指向const的指针 、引用、指针
查看>>