Android(安卓)View 随手指移动
概述
Android中的滑动事件,实际上就是View的移动,原理和动画相似.本质就是不断的改变View的位置,.View的滑动我们需要了解一个类MotionEvent.
MotionEvent中封装了一些与触摸相关的东西,比如触摸事件Action,触摸坐标等,在一般View 的触摸事件中都包含这样一个参数.
既然是View的位置移动,那么在移动的过程中,我们都有哪些方法来改变一个View 的位置呢,
onTouchEvent
在View 类中,我们知道有一个layout方法是给View定位的 ,结合onTouchEvent
方法 ,我们可以很好的实现一个View的移动.
int lastX, lastY; @Override public boolean onTouchEvent(MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_MOVE: int offsetX = rawX - lastX; int offsetY = rawY - lastY; layout(getLeft()+offsetX, getTop()+offsetY, getRight()+offsetX, getBottom()+offsetY); lastX = rawX; lastY = rawY; break; } return true; }
这里面使用了绝对坐标,使用绝对坐标的时候,需要在每次ACTION_MOVE
后重新设置出事坐标.
offsetLeftAndRight()
使用offsetLeftAndRight();offsetTopAndBottom();
方法,通过设置偏移量来滑动View
int lastX, lastY; @Override public boolean onTouchEvent(MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_MOVE: int offsetX = rawX - lastX; int offsetY = rawY - lastY; //layout(getLeft()+offsetX, // getTop()+offsetY, // getRight()+offsetX, // getBottom()+offsetY); offsetLeftAndRight(offsetX); offsetTopAndBottom(offsetY); lastX = rawX; lastY = rawY; break; } return true; }
LayoutParams
LayoutParams
,使用LayoutParams滑动View,通过改变布局参数来达到滑动View的目的.
int lastX, lastY; @Override public boolean onTouchEvent(MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_MOVE: int offsetX = rawX - lastX; int offsetY = rawY - 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); lastX = rawX; lastY = rawY; break; } return true; }
ScrollTo() ScrollBy()
使用ScrollTo() 和ScrollBy()
方法来改变View 的位置.
int lastX, lastY; @Override public boolean onTouchEvent(MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_MOVE: int offsetX = rawX - lastX; int offsetY = rawY - 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); ((View) getParent()).scrollBy( -offsetX, -offsetY); lastX = rawX; lastY = rawY; break; } return true; }
这里需要注意的是
1.首先我们的ScrollTo() and ScrollBy()
方法移动的是View的Content
2.我们移动的是画布,因此需要设置相反的值,才能让View 跟随手指移动.
Scroller
使用Scroller类来移动View,与ScrollBy()方法关系紧密,ScrollBy()移动是瞬时完成,Scroller类在ACTION_MOVE
中对偏移量进行划分,达到平滑效果.我们需要三个步骤
mScroller = new Scroller(context);
@Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }
case MotionEvent.ACTION_UP: ViewGroup viewGroup = (ViewGroup) getParent(); mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY()); invalidate(); break;
Property Animation
Android 属性动画,
int w = text.getWidth(); int screenW = UiUtil.getScreenWidth(); int transX = screenW - w; ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);
ViewDragHelper
使用v4包中的ViewDragHelper能很好的实现View的滑动和事件分发,典型谷歌官方的 Drawerlayout
ViewDragHelper实现QQ侧滑效果DragLayout[github]
更多相关文章
- 编译 Android(安卓)版本的 Opus 音频编解码库的方法
- Android(安卓)坐标系与视图坐标系图解
- android中进程与线程
- Android(安卓)下拉刷新框架实现、仿新浪微博、QQ好友动态滑到底
- Service与Android系统设计(2)-- Parcel
- 状态栏框架-- 深入Android应用开发:核心技术解析与最佳实践
- 关于Handler技术
- Android状态保存与恢复
- Android学习笔记之ImageSwitcher