抄自《Android开发艺术探索》
之前看自定义View时候的书摘,觉得应该会有用,分享出来以供参考。
View基础知识
位置参数
view位置由四个属性决定,分别为
top(左上角的纵坐标)
left(左上角的横坐标)
bottom(右下角的纵坐标)
right(右下角的横坐标)
这四个属性是相对于父容器的相对坐标。
若想获取控件在屏幕中的位置可使用以下代码
int[] location = new int[2];
v.getLocationOnScreen(location);
x = location[0];
y = location[1];
大概就是图1那个样子,图丑见谅。。
图1 View位置属性
从3.0开始,View增加了几个额外参数
x,y,translationX,translationY
x,y,是View左上角的坐标,其中,x = left + translationX,y = right + translationY
translationX,translationY,是View左上角相对于父容器的偏移量,默认为0
这四个变量主要服务于View 的平移,上一组四个变量针对的是View的原始坐标信息,这一组四个变量在位移时会发生改变
另外,这两组变量,系统都提供与之匹配的get,set方法。
触摸事件
ACTION_DOWD 手指触碰到屏幕
ACTION_MOVE 手指在屏幕上移动
ACTION_UP 手指从屏幕拿开
一次触摸事件,只会有一次DOWN以及一次UP事件响应,会有多次MOVE事件响应。
获取点击事件发生坐标有两种方法,getX/getY可以获取相对坐标,getRawX/getRawY可以获取绝对坐标,绝对坐标相对于屏幕。
TouchSlop是系统区分滑动事件还是点击事件的界限,默认值通过ViewConfiguration.get(getContext()).getScaledDoubleTapSlop()获取,在做自定义事件的时候推荐使用系统默认值。
VelocityTracker速度追踪器,系统提供方法可以获得手指在单位时间内的滑动速度
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(motionEvent);
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
int velocityY = (int) velocityTracker.getYVelocity();
对应于这个时间,我理解为采样率,取单位时间起始时,触摸位置,以及单位时间结束时,触摸位置,生成向量来计算速度。这个速度可正可负。
使用结束记得回收内存。
velocityTracker.clear();
velocityTracker.recycle();
GestureDetector事件监听器,是一个工具性的类,可以简化点击事件的处理。
通过实现OnGestureListener接口,可以监听处理
方法名 | 描述 |
---|---|
onDown | 轻触屏幕一瞬间,由一个ACTION_DOWN触发 |
onShowPress | 轻触屏幕一瞬间,且没有松开或者拖动,强调没有松开或拖动的状态,由一个ACTION_DOWN触发 |
onSingleTapUp | 轻触屏幕后松开,理解为单击,伴随一个ACTION_UP触发 |
onScroll | 手指按下屏幕并拖动,由一个ACTION_DOWN,多个ACTION_MOVE触发 |
onLongPress | 长按 |
onFling | 快速滑动,由一个ACTION_DOWN,多个ACTION_MOVE,一个ACTION_UP触发 |
通过实现OnDoubleTapListener接口,可以监听判断一些双击类型的事件
方法名 | 描述 |
---|---|
onSingleTapConfirmed | 严格的单击事件。onSingleTapConfirmed是触发之后还可能会触发双击事件(onDoubleTap),onSingleTapUp就只是一个单击,而不会是双击之中的第一个单击 |
onDoubleTap | 双击,就是连续两次单击,在双击过程中,只会触发一次。 |
onDoubleTapEvent | 双击行为,在双击过程中,ACTION_DOWN,ACTION_MOVE,ACTION_UP都会触发回调 |
个人理解, 事件监听主要用于复杂事件的监听,比如onSingleTapConfirmed,onFling,onDoubleTap这种自己实现会比较麻烦的触摸事件,其他的简单事件自己手写会比较好。
PS:测试事件是否正确响应的时候建议重写Activity的dispatchTouchEvent或者onTouchEvent来进行,如果绑定到系统控件上进行测试的时候,可能会因为控件本身对于事件的拦截规则,导致事件响应与预期差别较大。
View滑动
scrollBy是基于当前位置的滑动
scrollTo是基于所传递参数的绝对滑动
mScrollX的值总是等于View左边缘跟View内容左边缘在水平方向上的距离
mScrollY的值总是等于View上边缘跟View内容上边缘在垂直方向上的距离
这两个值以View边缘为坐标零点,可以为负值。并且可以通过get方法获取响应的值。
scrollBy跟scrollTo只能改变View内容的位置,而不能改变View在布局中的位置。
View滑动有三种策略,第一种是借助scroll相关属性,第二种是通过动画(transation相关属性,见上文触摸事件部分),第三种就是改变布局参数,比如margin,padding相关属性。
三种方法的优略如下,
借助scroll相关属性,操作简单,但只能移动View的内容,局限较大。
借助动画,操作简单,主要试用与没有交互的View,并且容易实现复杂效果。
改变布局参数,操作稍微复杂,适用于有交互的View。
个人理解,难免有错误纰漏,欢迎指正。转载请注明出处。
网友评论