摘录自博客地址
- Configuration
- ViewConfiguration
- GestureDetector
- VelocityTracker
- Scroller
- ViewDragHelper
以上的工具封装了我们经常会用到的方法,比如拖拽View,计算滑动速度,View的滚动,手势处理等等。如果我们自己去实现这些方法会比较繁琐,而且容易出一些bug。所以,作为自定义View系列教程的开端,先介绍一下这些常用的工具,以便在后续的学习和工作中使用。
Configuration
Configuration用来描述设备的配置信息。
比如用户的配置信息:locale和scaling等等
比如设备的相关信息:输入模式,屏幕大小, 屏幕方向等等
ViewConfiguration
ViewConfiguration提供了一些自定义控件用到的标准常量,比如尺寸大小,滑动距离,敏感度等等。
GestureDetector
手势监听
VelocityTracker
VelocityTracker用于跟踪触摸屏事件(比如,Flinging及其他Gestures手势事件等)的速率。
Scroller
scrollTo()和scrollBy()
ViewDragHelper
在项目中很多场景需要用户手指拖动其内部的某个View,此时就需要在onInterceptTouchEvent()
和onTouchEvent()这两个方法中写不少逻辑了,比如处理:拖拽移动,越界,多手指的按下,加速
度检测等等。
摘录自博客地址
- MeasureSpec封装了父布局传递给子View的布局要求。
- MeasureSpec可以表示宽和高
- MeasureSpec由size和mode组成
MeasureSpec高2位代表SpecMode即测量模式,低30位为SpecSize规格大小
//获取SpecSize
int specSize = MeasureSpec.getSize(measureSpec)
//获取specMode
int specMode = MeasureSpec.getMode(measureSpec)
//当然,也可以通过这两个值生成新的MeasureSpec
int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);
SpecMode一共有三种
- MeasureSpec.EXACTLY模式表示:父容器已经检测出子View所需要的精确大小;
- MeasureSpec.AT_MOST模式表示:父容器未能检测出子View所需要的精确大小,但是指定了一个可用大小即specSize,在该模式下,View的测量大小不能超过SpecSize;
- MeasureSpec.UNSPECIFIED这种模式一般用作Android系统内部,或者ListView和ScrollView等滑动控件,父容器不对子View的大小做限制。
自定义View的流程 measure->layout->draw measure: 测量view的宽和高; layout: 确定View在父容器中的位置; draw: 将View绘制在屏幕上; performTraversals会依次调用performMeasure、performLayout和performDraw三个方法; 具体的: performMeasure->measure->onMeasure
http://blog.csdn.net/guolin_blog/article/details/9097463
答:从源码中可以看出,这两个方法都是在View的dispatchTouchEvent中调用的,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。 另外需要注意的是,onTouch能够得到执行需要两个前提条件,第一mOnTouchListener的值不能为空,第二当前点击的控件必须是enable的。因此如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。
如果你阅读了Android滑动框架完全解析,教你如何一分钟实现滑动菜单特效 这篇文章,你应该会知道滑动菜单的功能是通过给ListView注册了一个touch事件来实现的。如果你在onTouch方法里处理完了滑动逻辑后返回true,那么ListView本身的滚动事件就被屏蔽了,自然也就无法滑动(原理同前面例子中按钮不能点击),因此解决办法就是在onTouch方法里返回false。
提这个问题的朋友是看过了Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来 这篇文章。当时我在图片轮播器里使用Button,主要就是因为Button是可点击的,而ImageView是不可点击的。如果想要使用ImageView,可以有两种改法。第一,在ImageView的onTouch方法里返回true,这样可以保证ACTION_DOWN之后的其它action都能得到执行,才能实现图片滚动的效果。第二,在布局文件里面给ImageView增加一个android:clickable="true"的属性,这样ImageView变成可点击的之后,即使在onTouch里返回了false,ACTION_DOWN之后的其它action也是可以得到执行的。
http://blog.csdn.net/guolin_blog/article/details/9153747
1.Android事件分发是先传递到ViewGroup,再由ViewGroup传递到View的。
2.在ViewGroup中可以通过onInterceptTouchEvent方法对事件传递进行拦截,onInterceptTouchEvent方法返回true代表不允许事件继续向子View传递,返回false代表不对事件进行拦截,默认返回false。
3.子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件。