初步解析View的滑动

View的滑动方式有很多,在学习View的滑动之前,我们先了解下View是怎么定位的。

View坐标系

1.View自身坐标

  • getTop():获取自身顶部到父布局顶部的距离

  • getLeft():获取View自身左边到父布局左边的距离

  • getRight():获取View自身到父布局左边的距离

  • getBottom():获取View自身到父布局顶部的距离

2.确定点击位置坐标
当我们点击屏幕时,会触发点击事件。MotionEvent提供了几种方法获取点击坐标

  • getX():点击事件距离自身View左边的距离
  • getY():点击事件距离自身View顶边的距离
  • getRawX():点击事件距离整个屏幕左边的距离
  • getRawY():点击事件距离整个屏幕顶边的距离

View的滑动

view的滑动是当点击事件传递到View时,记下触摸点,当手指移动时,记录移动后的坐标并计算出偏移量,通过偏移量来改变View的坐标。
1.layout()

public boolean onTouchEvent(MotionEvent event){
		int x = (int)event.getX();
		int y = (int)event.getY();
		switch(event.getAction()){
			case MotionEvent.ACTION_DOWN:
   				 lastX = x;
   				 lastY = y;
   					 break;
   			case MotionEvent.ACTION_MOVE:
    			int offsetX = x - lastX;
    			int offsetY = y - lastY;
    			layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
    				break;	 
}
}

2.offsetLeftAndRight()与offsetTopAndBottom()
将ACTION_MOVE中的layout方法替换就行

case MotionEvent.ACTION_MOVE:
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    offsetLeftAndRight(offsetX);
    offsetTopAndBottom(offsetY);
    break;

3.LayoutParams
通过改变LayoutParams来改变View 的布局参数,便改变了View的位置,同样替换ACTION_MOVE中的代码

int offsetX = x - lastX;
    int offsetY = y - lastY;
    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
    params.leftMargin = getLeft() + offsetX;
    params.topMargin = getTop() + offsetY;
    break;

4.scrollTo和scrollBy
scrollTo表示移动到具体的坐标点位置,scrollBy表示在原来View的基础上移动偏移量。需要注意的是,移动的偏移量要取反。因为这两个方法移动的是其内部的内容。

case MotionEvent.ACTION_MOVE:
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    ((View)getParent()).scrollBy(-offsetX,-offsetY);
    break;

5.Scroller
可以通过Scroller来实现View移动的连续性。Scroller需要与View的computeScroll()方法配合。

scroller = new Scroller(context);

重写computeScroll方法,系统在调用draw()方法时,会调用此方法。在该方法中,调用父类的scrollTo方法,通过Scroller获取当前滚动值,滑动一小段距离后,调用invalidate()方法进行重绘。

@Override
public void computeScroll() {
    super.computeScroll();
    if (scroller.computeScrollOffset()) {
        offsetLeftAndRight(scroller.getCurrX()-getLeft());
        offsetTopAndBottom(scroller.getCurrY()-getTop());
        invalidate();
    }
}

最后调用Scroller中的startScroll方法。

scroller.startScroll(getLeft(),getTop(),-getLeft()+initX,-getTop()+initY,2000);

猜你喜欢

转载自blog.csdn.net/qq_38256015/article/details/84110153
今日推荐