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;
}
});
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGF3YW5nYW5iYW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
能够看到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中事件分发的过程知识.这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpa ...
- Android自己定义组件系列【5】——进阶实践(2)
上一篇<Android自己定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这 ...
- Android自己定义组件系列【4】——自己定义ViewGroup实现双側滑动
在上一篇文章<Android自己定义组件系列[3]--自己定义ViewGroup实现側滑>中实现了仿Facebook和人人网的側滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布 ...
- Android自己定义组件系列【3】——自己定义ViewGroup实现側滑
有关自己定义ViewGroup的文章已经非常多了,我为什么写这篇文章,对于刚開始学习的人或者对自己定义组件比較生疏的朋友尽管能够拿来主义的用了,可是要一步一步的实现和了解当中的过程和原理才干真真脱离别 ...
- Android自己定义组件系列【5】——高级实践(1)
在接下来的几篇文章将任老师的博文<您可以下拉PinnedHeaderExpandableListView实现>骤来具体实现.来学习一下大神的代码并记录一下. 原文出处:http://blo ...
- Android自己定义组件系列【1】——自己定义View及ViewGroup
View类是ViewGroup的父类,ViewGroup具有View的全部特性.ViewGroup主要用来充当View的容器.将当中的View作为自己孩子,并对其进行管理.当然孩子也能够是ViewGr ...
- Android自己定义组件系列【2】——Scroller类
在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友能够先看<自己定义View及ViewGroup> scrollTo和scrollBy尽管实 ...
- Android自己定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了非常多插件,可是非常多时候我们须要依据详细项目自己定义这些图表,这一篇文章我们一起来看看怎样在Android中使用Can ...
- Android自己定义组件系列【8】——面膜文字动画
我们掩盖文字动画Flash中非经货共同体共同,由于Android应用程序开发人员做你想要做这个动画在应用程序中去?本文中,我们看的是如何自己的定义ImageView来实现让一张文字图片实现文字的遮罩闪 ...
随机推荐
- 全网最详细python中socket套接字send与sendall的区别
将数据发送到套接字. 套接字必须连接到远程套接字. 返回发送的字节数. 应用程序负责检查是否已发送所有数据; 如果仅传输了一些数据, 则应用程序需要尝试传递剩余数据.(需要用户自己完成) 将数据发送 ...
- MyInt的简单实现
#include <iostream> using namespace std; class CMyInt{ private: int value; public: CMyInt(int ...
- python week08 并发编程之多进程--理论部分
一 什么是进程 进程:正在进行的一个过程或者说一个任务. 而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): Jame在一个时间段内有很多任务要做:python学习任 ...
- Mutual Training for Wannafly Union #8 D - Mr.BG Hates Palindrome 取余
Mr.BG is very busy person. So you have been given enough time (1000 milliseconds) to help him. Mr. B ...
- Pycharm脚本通用部分设置
Python脚本经常要设置同样的注释内容,Pycharm里面提供的模板可以很好的实现这个需求. 查找: File->settings->Editor->File and Code T ...
- javascript学习笔记 - 引用类型 Array
二 Array 1.可以通过length属性删除或创建新的数组项 arr = [1,2,3]; arr.length = 4;//增加 [1,2,3,undefined] arr.length = 2 ...
- 解决Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianpos.git/': Couldn't resolve host 'git.coding.net'
代码改变世界 github push 出现问题 Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianp ...
- 【Luogu】P3704数字表格(莫比乌斯反演+大胆暴力)
题目链接 给你们讲个笑话:Konoset是个sb,他快速幂的时候把幂次取模了. 原式差不多就是这样吧$\prod\limits_{i=1}^{n}\prod\limits_{j=1}^{m}f[gcd ...
- kb-01-e<取余操作,宽搜,巧妙>;
题目描述: n属于1到200,找到对应的一个数只含有0和1,并且是n的倍数: 分析: 本题有几个数会是大数:所以要考虑大数: 用到余数的性质:例如n=6,1%6=1: 1*10%6=4: ...
- [luoguP1640] [SCOI2010]连续攻击游戏(二分图最大匹配)
传送门 我们将每一个属性和物品连边,然后枚举从小到大属性跑匈牙利,直到找不到连边 #include <cstdio> #include <cstring> #include & ...