想法材料大多出自Android开发艺术探索。
View在Android中是一个重要的概念,作用堪比四大组件。
因为系统提供的控件有时候是不能满足需求的,所以我们需要根据需求来进行新控件的自定义,而控件的自定义需要对Android中View体系有深入的了解
解决滑动冲突 需要对View事件的分发机制有所了解
View基础知识
1. 什么是View
View是Android当中所有控件的基类。不管是简单的Button还是复杂的RelativeLayout,他们共同的基类都是View.同时ViewGroup也继承了View,意味着view本身可以是单个控件也可以是多个控件组成的一组控件,通过这种关系形成了View树的这种结构
2. View的位置参数
View的位置主要由它的四个顶点来决定,分别对应于View的四个属性:top、left、right、bottom。
top——-左上角纵坐标
left——-左上角横坐标
right—–右下角横坐标
bottom–右下角纵坐标
图片引用自百度搜索
根据图,我们很容易得出View的宽高和坐标关系
width = right - left
height = bottom - top
从Android3.0开始,View增加额外参数translationX和translationY,是View左上角相对于父容器的偏移量。默认值为0,view也为它们提供了get/set方法。需要注意的是,View在平移过程中,top和left值不会发生改变,改变的是X,Y,translationX,translationY这四个参数
3. MotionEvent和TouchSlop对象
MotionEvent
手指触碰屏幕产生一系列事件中,典型的有如下几种
1. ACTION_DOWN 手指落下刚接触屏幕
2. ACTION_MOVE 手指滑动屏幕
3. ACTION_UP 手指离开屏幕
通过MotionEvent对象,我们可以获得点击事件发生的X,Y坐标。两种方法getX/getY和getRawX/gerRawY (用法看图)
TouchSlop
TouchSlop是系统所能识别处的被认为是滑动的最小距离,滑动距离太短,系统不认为它是滑动。这是一个常量,和设备有关,在不同设备上的这个值是不一样的。
通过如下方式获取这个常量 ViewConfiguration.get(getContext()).getScaledTouchSlop()
4.VelocityTracker/GestureDetector/Scroller对象
VelocityTracker
速度追踪者,用于追踪手指在滑动中的速度。包括水平和竖直方向的速度。使用方法很简单
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker .addMovement(event);
获取速度必须先计算速度。可以使用getXVelocity() 或getXVelocity()获得横向和竖向的速率到速率时,但是使用它们之前请先调用computeCurrentVelocity(时间单位ms)来初始化速率的单位 。不需要使用它的时候调用clear(),recycle()方法来重载并回收内存。
GestureDetector
手势检测,用于辅助检测用户的单机,滑动,长按,双击等行为。主要是通过它的onTouchEvent(event)方法完成了不同手势的识别.
GestureDetector这个类对外提供了两个接口和一个外部类
接口:OnGestureListener,OnDoubleTapListener
// implements GestureDetector.OnGestureListener
将会实现如下几个方法
OnGestureListener
- OnDown(MotionEvent e)//触摸屏幕的一瞬间
- onShowPress(MotionEvent e)//按下的时间超过瞬间,尚未松开或拖动
- onLongPress(MotionEvent e)//长按不放
- onSingleTapUp(MotionEvent e)//单击行为,接触屏幕松开
- onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
//快速滑动松开 - onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY)
//按下屏幕拖动
OnDoubleTapListener
- onDoubleTap 双击,由两次连续的单击组成,不可能和onSingleTapConfirm共存
- onSingleTapConfirm 严格的单机行为 注意和onSingleTapUp的区别 只可能是单击而不是双击中的一次单击
- onDoubleTapEvent 表示发生了双击行为 ACTION_DOWN,ACTION_MOVE,ACTION_UP 都会触发此回调
实际开发中可以不使用GestureDetector,完全可以在自己的View中的onTouchEvent方法中实现所需的监听。如果只是监听滑动相关的,建议在自己的onTouchEvent中实现,监听双击这种行为的话,那么就使用GestureDetector
Scroller的使用
弹性滑动对象,用于实现View的弹性滑动。使用View的scrollTo/scrollBy方法来进行滑动时,其过程是瞬间完成的,没有过渡效果的用户体验是不好的。这个时候需要用到Scroller,其过程不是瞬间完成的,而是在一定时间间隔内完成的。Scroller本身不能让View弹性滑动,它需要和View的computeScroll方法配合使用才能完成
Scroller scroller = new Scroller(mContext);
//缓慢滚动到指定位置
private void smoothScrollTo(int destX,int destY){
int scrollX = getScrollX();
int delta = destX - scrollX;
//1000ms内滑向destX,效果就是慢慢滑动
mScroller.startScroll(scrollX,0,delta,0,1000);
invalidate();
}
public void computeScroll(){
if(mScroller.computeScrollOffset(){
scrollTo(mScroller.getCurrX,mScroller.getCurrY());
postInvalidate();
}
}