Android自定义组件系列【6】——进阶实践(3)
上一篇《Android自定义组件系列【5】——进阶实践(2)》继续对任老师的《可下拉的PinnedHeaderExpandableListView的实现》进行了分析,这一篇计划中间插一段“知识点”,对Android中的事件分发机制进行解析。细心的朋友可能会发现,打开大牛写的Android项目,里面很多组件都是自定义的(这就是为什么界面和体验这么吸引你的原因),但是要灵活的去自定义组件就必须对手势(也就是各种监听)必须熟悉,能处理好事件之间的关系。
先看一段代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
Log.i(TAG, "onClick");
}
}); button.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "onTouch down");
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "onTouch move");
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "onTouch up");
break;
default:
break;
}
return false;
}
});
}
可以看到onTouch方法会被先调用,然后才调用onClick方法,如果我们将上面onTouch方法的返回值改为true,则onClick方法不会被调用,事件将被onTouch方法消费。
还记得前几篇文章中都会使用一个dispatchTouchEvent的方法吗.
public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
可以看到在dispatchTouchEvent中调用了onTouch方法,所以会先于onClick方法调用。如果onTouch返回true后dispatcheTouchEvent就会直接返回true则不会再执行其他方法。
在Android系统中每个ViewGroup子类都具有如下三个方法:
public boolean dispatchTouchEvent(MotionEvent event) :用来分发TouchEvent
public boolean onInterceptTouchEvent(MotionEvent event) :用来拦截TouchEvent
public boolean onTouchEvent(MotionEvent event) :处理TouchEvent
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<com.kris.touch.widget.TouchView
android:id="@+id/view_out"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:gravity="center">
<com.kris.touch.widget.TouchView
android:id="@+id/view_mid"
android:layout_width="300px"
android:layout_height="400px"
android:background="#f00"
android:gravity="center">
<com.kris.touch.widget.TouchView
android:id="@+id/view_center"
android:layout_width="150px"
android:layout_height="150px"
android:background="#000"
android:gravity="center"
android:clickable="true">
</com.kris.touch.widget.TouchView>
</com.kris.touch.widget.TouchView>
</com.kris.touch.widget.TouchView>
</LinearLayout>
首先触摸事件(ACTION_DOWN)发生后,系统调用Activity的dispatchTouchEvent方法,分发事件。根据触摸事件的坐标,将此事件传递给out(最外层)的dispatchTouchEvent处理。out则调用onInterceptTouchEvent方法判断事件是否由自己来处理,还是向下传递给子View.如果out不处理该事件会根据事件产生坐标分发给它的直接子View.
图中center组件是可点击的(clickable)组件,表示能处理Touch事件,所以center中的onInterceptTouchEvent方法将事件传递给center
TouchEvent中,如果返回值是true,则说明消耗(消费)了这个事件,不会再向下传递。如果返回值是false,则没有消耗事件,会继续传递下去。如果center中不会处理事件(android:clickable="false"),事件不会被center的onTouchEvent消费,则事件会层层逆向回到activity。
关于事件分发机制就先了解到这里,下一篇接着分析......
Android自定义组件系列【6】——进阶实践(3)的更多相关文章
- Android自定义组件系列【7】——进阶实践(4)
上一篇<Android自定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识,这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpan ...
- Android自定义组件系列【5】——进阶实践(2)
上一篇<Android自定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这一 ...
- Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动
在上一篇文章<Android自定义组件系列[3]--自定义ViewGroup实现侧滑>中实现了仿Facebook和人人网的侧滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布局示 ...
- Android自定义组件系列【3】——自定义ViewGroup实现侧滑
有关自定义ViewGroup的文章已经很多了,我为什么写这篇文章,对于初学者或者对自定义组件比较生疏的朋友虽然可以拿来主义的用了,但是要一步一步的实现和了解其中的过程和原理才能真真脱离别人的代码,举一 ...
- Android自定义组件系列【5】——进阶实践(1)
接下来几篇文章将对任老师的博文<可下拉的PinnedHeaderExpandableListView的实现>分步骤来详细实现,来学习一下大神的代码并记录一下. 原文出处:http://bl ...
- Android自定义组件系列【12】——非UI线程绘图SurfaceView
一.SurfaceView的介绍 在前面我们已经会自定义View,使用canvas绘图,但是View的绘图机制存在一些缺陷. 1.View缺乏双缓冲机制. 2.程序必须重绘整个View上显示的图片,比 ...
- Android自定义组件系列【1】——自定义View及ViewGroup
View类是ViewGroup的父类,ViewGroup具有View的所有特性,ViewGroup主要用来充当View的容器,将其中的View作为自己孩子,并对其进行管理,当然孩子也可以是ViewGr ...
- Android自定义组件系列【17】——教你如何高仿微信录音Toast
一.Toast介绍 平时我们在Android开发中会经常用到一个叫Toast的东西,官方解释如下 A toast is a view containing a quick little message ...
- Android自定义组件系列【15】——四个方向滑动的菜单实现
今天无意中实现了一个四个方向滑动的菜单,感觉挺好玩,滑动起来很顺手,既然已经做出来了就贴出来让大家也玩弄一下. 一.效果演示 (说明:目前没有安装Android模拟器,制作的动态图片太卡了,就贴一下静 ...
随机推荐
- Apache通用日志工具commons-logging和Log4j使用总结
转自:https://blog.csdn.net/lzl13391522110/article/details/53758536 Apache通用日志工具commons-logging和Log4j使用 ...
- 理性分析 C++(-O2) 和 JS 的性能差距
laptop: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz.. Test1: 最后一行:时间(ms) #pragma GCC optimize("O2& ...
- 【习题 7-8 UVA-12107】Digit Puzzle
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 迭代加深搜索. 枚举最大层数.(也即改变的数字个数 然后枚举第一个改哪个数字,第二个改哪个数字.. 一定要注意字典序问题. 每次优先 ...
- 关于android主线程异常NetworkOnMainThread不能訪问网络
今天在学习的过程中遇到了NetworkOnMainThread的异常,关于这个异常问题在android sdk 4.0版本号上,这个问题可能比較常见,查了许些资料大多都是大概解说原因,可是没有解说到详 ...
- 【iOS开发-29】解决方式:TabBar的图片不显示,仅仅显示灰色的正方形
(1)现象 tabbar上的图片变成一块正方形的灰色块块,原先的图片没有了. (2)原因 tabbar上的图片本质上不是一个图片.而是一个形状图片.系统对我们使用的图片也仅仅是把当中的形状" ...
- 黑马day01 xml 的解析方式
XML编程:利用java程序去增删改查(CRUD)xml中的数据 解析思想: dom解析 sax解析 基于这两种解析思想市面上就有了非常多的解析api sun jaxp既有dom方式也有sax方式,而 ...
- Android Gradle统一依赖管理
目的: 避免在依赖包出新版本时,需要对每个module中的build.gradle文件都进行修改(如appcompat-v7包),使用这种方式即只需一次修改. 方法一 在项目的根目录创建一个gradl ...
- RMAN异机复制数据库(不同路径)
1.恢复参数文件 设置环境变量: export ORACLE_SID=hncdfhq 登录RMAN: rman target / 在RMAN里把数据库起到nomount状态: startup nomo ...
- LeetCode Algorithm 133_Clone Graph
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- 微服务实战(三):深入微服务架构的进程间通信 - DockOne.io
原文:微服务实战(三):深入微服务架构的进程间通信 - DockOne.io [编者的话]这是采用微服务架构创建自己应用系列第三篇文章.第一篇介绍了微服务架构模式,和单体式模式进行了比较,并且讨论了使 ...