坐标系
- android 坐标系
//int[] location = new int[2];
getLocationOnScreen(int location[]);获取view的左上角在android坐标系的坐标
getRawX(); 触控过程中,获取触点在android坐标系的坐标
- View坐标系
getX() getY();
滑动的七种实现
1. layout
2. offsetLeftAndRight,offsetTopAndBottom
3. LayoutParams
4. scrollTo,scrollBy
移动的是View的Content。如果在ViewGroup使用,滑动的是它的子View,而在View中滑动的是它的内容(TextView content是它的文本)
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getX();
lastY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
//1.((View) getParent()).scrollBy(-offsetX, -offsetY);
//2.layout(getLeft() + offsetX,getTop() + offsetY,getRight() + offsetX,getBottom() + offsetY);
//3.offsetLeftAndRight(offsetX);offsetTopAndBottom(offsetY);
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX;
layoutParams.topMargin = getTop() + offsetY;
setLayoutParams(layoutParams);
break;
}
return true;
}
5. Scroller
//1.在构造函数中初始化 Scroller
mScroller = new Scroller(context,new BounceInterpolator());
//2.重写 view 的 computeScroll
@Override
public void computeScroll() {
super.computeScroll();
// 判断Scroller是否执行完毕
if (mScroller.computeScrollOffset()) {
((View) getParent()).scrollTo(
mScroller.getCurrX(), //获取当前的滑动坐标
mScroller.getCurrY());
// 通过重绘来不断调用computeScroll
invalidate();
}
}
//3.startScroll 设置参数
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getX();
lastY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
((View) getParent()).scrollBy(-offsetX, -offsetY);
break;
case MotionEvent.ACTION_UP:
// 手指离开时,执行滑动过程
View viewGroup = ((View) getParent());
mScroller.startScroll( //回到原来的位置
viewGroup.getScrollX(), //总共滑动的距离
viewGroup.getScrollY(),
-viewGroup.getScrollX(),
-viewGroup.getScrollY());
invalidate();
break;
}
return true;
}
scroller.gif
Scroll的绘制原理:
重点在于 mScroller.startScroll(...)下面的 invalidate 方法,这将导致 View 进行重绘,View 的 draw 方法又会去调用 computeScroll 方法,computeScroll 在 View中是个空实现。这就是为什么一定要 Override computeScroll 的原因。
网友评论