0x01:位置基础
View的位置主要由4个顶点决定,分别对应View的四个位置属性:left,top,right,bottom;这些位置对于父容器来说,是相对坐标位置。
在andriod中,x轴正方向为右,y轴正方向为下
x,y,translationX,translationY:
对于父容器,x,y分别为View相对父容器的左上角的坐标
translationX,translationY是View相对与父容器的位移偏移量。
x=left+translationX;
y=right+translationY;
0x02:MotionEvent
ACTION_DOWN:手指刚接触屏幕
ACTION_MOVE:手指在屏幕上移动
ACTION_UP:手指从屏幕松开的一瞬间
我们可以通过MotionEvent对象的getX(),getY()获得手指位置相对父布局的x,y坐标
通过MotionEvent对象的getRawX(),getRawY()获得手指相对手机屏幕左上角的x,y坐标
0x03:TouchSlop
TouchSlop是能被系统识别的最小的滑动距离,是一个常量,当滑动的距离小于这个常量,系统不认为滑动了。
获得常量的方式:
ViewConfiguration.get(this).getScaledTouchSlop()
意义:处理滑动时,可以利用这个常量来做一些过滤。
0x04:VelocityTracker
速度追踪,用于追踪手指在滑动过程中的速度,包括水平和垂直方向的速度。
VelocityTracker velocityTracker=VelocityTracker.obtain();
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
Util.logd("Vx:"+velocityTracker.getXVelocity()+",Vy:"+velocityTracker.getYVelocity());
velocityTracker.clear()
velocityTracker.recycle()
在不需要的时候要及时调用clear()方法和recycle()方法。
另外,在调用velocityTracker.getXVelocity()方法与velocityTracker.getYVelocity()方法之前需要调用computeCurrentVelocity方法,这里的速度指的是在一段时间内手指所划过的像素数,1000表示在1000ms内手指划过的像素,加入为100,则速度为100像素/s,计算速度的公式可以用:
速度=(终点位置-起点位置)/时间段
表示
0x05:GestureDetector
手势检测,用于辅助检测用户的单击,滑动,长按,双击等行为。
- 构造GestureDetector对象,需要传入一个OnGestureListener接口
- gestureDetector.setIsLongpressEnabled(false);解决长按屏幕无法拖动的情况
- 接管并消费View的onTouchEvent
//1
gestureDetector=new GestureDetector(new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
Toast.makeText(getContext(),"按下",Toast.LENGTH_SHORT).show();
//手指触摸屏幕一瞬间,由1个ACTION_DOWN触发
return true;
}
@Override
public void onShowPress(MotionEvent e) {
Toast.makeText(getContext(),"onShowPress",Toast.LENGTH_SHORT).show();
//手指刚接触屏幕,尚未拖动或者松开,描述的是ACTION_DOWN下不动的那个状态
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Toast.makeText(getContext(),"singleTapUp",Toast.LENGTH_SHORT).show();
//手指轻轻触摸屏幕后松开,由ACTION_UP触发
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Toast.makeText(getContext(),e1.toString()+e2.toString(),Toast.LENGTH_SHORT).show();
//手指按下并拖动,由1个ACTION_DOWN和多个ACTION_MOVE触发,是拖动行为
return true;
}
@Override
public void onLongPress(MotionEvent e) {
Toast.makeText(getContext(),"longPress",Toast.LENGTH_SHORT).show();
//用户长按并未松动,一直按压屏幕不放
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Toast.makeText(getContext(),"flying",Toast.LENGTH_SHORT).show();
//用户按下屏幕,快速滑动后松开,由1个ACTION_DOWN和多个ACTION_MOVE以及多个ACTION_UP触发,这是快速滑动行为
return true;
}
});
gestureDetector.setIsLongpressEnabled(false);
}
//2
gestureDetector.setIsLongpressEnabled(false);
//3
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
0x06:Scroller
private MyScroller scroller;
scroller=new MyScroller(context);
public void smoothScrollTo(int destX,int destY)
{
int scrollX=getScrollX();
int deltaX=destX-scrollX;
int scrollY=getScrollY();
int deltaY=destY-scrollY;
scroller.startScroll(scrollX,scrollY,deltaX,deltaY,20000);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset())
{
((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
invalidate();
}
}
0x07:scrollTo与scrollBy
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
网友评论