android scroll
1.滑动的产生:监听用户用户触摸事件,并根据事件传入坐标,通过不断改变view的坐标,实现view跟随用户触摸的滑动而滑动。
1.1 android坐标系:屏幕左上角的顶点为坐标系的原点,这个点向右为x正轴,这个点向下为y轴正轴。
1.2 视图坐标系:和android坐标系x.y一样,只是坐标原点变成了父控件的左上角。
private void getxy(MotionEvent event) { // view提供的 View view = new View(BaseApplication.getContext()); float top = view.getTop(); //获取到view自身的顶边到其父布局顶边的距离 float left = view.getLeft(); int right = view.getRight(); int bottom = view.getBottom(); // MotionEvent提供的方法 // 获取点击事件距离控件左边的距离,视图坐标 int x = (int) event.getX(); int y = (int) event.getY(); // 获取点击事件距离整个屏幕左边的距离,即绝对坐标 float rawX = event.getRawX(); // 获取点击事件距离整个屏幕顶边的距离,即绝对坐标 float rawY = event.getRawY(); }
1.3触控事件 MotionEvent
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 单点触摸按下动作 break; case MotionEvent.ACTION_UP: // 单点触摸离开动作 break; case MotionEvent.ACTION_MOVE: // 触摸点移动事件 break; case MotionEvent.ACTION_CANCEL: // 触摸动作取消 break; case MotionEvent.ACTION_OUTSIDE: // 触摸动作超出边界 break; case MotionEvent.ACTION_POINTER_DOWN: // 多点触摸按下动作 break; case MotionEvent.ACTION_POINTER_UP: // 多点离开动作 break; } return super.onTouchEvent(event); }
2.实现滑动的七种方法
2.1 重写view在onTouchEvent中通过 layout方法设置
int lastX ; int lastY ; @Override 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; } return true; }2.2 计算出偏移量了后,通过offsetLeftAndRight()和offsetTopAndBottom()来设置
int lastX ; int lastY ; @Override 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); offsetLeftAndRight(offsetX); offsetTopAndBottom(offsetY); break; } return true; }2.3 通过修改LayoutParams来动态修改一个布局的位置参数。
int lastX ; int lastY ; @Override 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); // offsetLeftAndRight(offsetX); // offsetTopAndBottom(offsetY); ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams(); layoutParams.leftMargin = getLeft()+offsetX; layoutParams.topMargin=getTop()+offsetY; setLayoutParams(layoutParams); break; } return true; }2.4通过scrollTo和scrollBy,注意这两个移动的是他里面的内容.如果只是一个view移动的是view的内容,如果是一个viewgroup移动的就是它里面的view
int lastX ; int lastY ; @Override 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; // scrollTo(offsetX,offsetY); // 获取到它的父控件调用scrollTo,另外注意这里设置的是负值 ((View) getParent()).scrollTo(-offsetX,-offsetY); break; } return true; }2.5 通过用Scroller类 实现平滑移动
在构造方法中实例化一个Scroller
@Override public void computeScroll() { super.computeScroll(); // 判断scroller是否执行完毕 if (scroller.computeScrollOffset()) { ((View)getParent()).scrollTo( scroller.getCurrX(), scroller.getCurrY()); // 通过重回来不断调用computeScroll invalidate(); } } int lastX; int lastY; @Override 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; // scrollTo(offsetX,offsetY); // 获取到它的父控件调用scrollTo ((View) getParent()).scrollTo(-offsetX, -offsetY); break; case MotionEvent.ACTION_UP: // 手指离开时执行滑动过程 View viewGroup = (View) getParent(); scroller.startScroll(viewGroup.getScrollX(), viewGroup.getScrollY(), -viewGroup.getScrollX(), -viewGroup.getScrollY()); invalidate(); break; } return true; }2.6 通过属性动画
2.7 通过ViewDragHelper