View位置的变化和触控操做都涉及到MotionEvent
类,MotionEvent
中封装了一些与触摸相关的东西,好比触摸事件Action
,触摸坐标等。移动View
无疑就是改变其位置,一般有如下几种方式。git
在View
类中,咱们知道有一个layout
方法是给View
定位的 ,结合onTouchEvent
方法 ,咱们能够很好的实现一个View
的移动.github
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; }12345678910111213141516171819202122232425262728293031323334
这里面使用了绝对坐标,使用绝对坐标的时候,须要在每次ACTION_MOVE
后从新设置初始坐标.web
使用offsetLeftAndRight();offsetTopAndBottom();
方法,经过设置偏移量来滑动Viewide
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; }12345678910111213141516171819202122232425262728293031323334353637
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; }123456789101112131415161718192021222324252627282930313233343536373839404142
使用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; }123456789101112131415161718192021222324252627282930313233343536373839404142434445
这里须要注意的是
1.首先咱们的ScrollTo() and ScrollBy()
方法移动的是View的Content
2.咱们移动的是画布,所以须要设置相反的值,才能让View
跟随手指移动.spa
使用Scroller
类来移动View
,与ScrollBy()
方法关系紧密,ScrollBy()
移动是瞬时完成,Scroller
类在ACTION_MOVE
中对偏移量进行划分,达到平滑效果.咱们须要三个步骤code
mScroller = new Scroller(context);1
@Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }12345678
case MotionEvent.ACTION_UP: ViewGroup viewGroup = (ViewGroup) getParent(); mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY()); invalidate(); break;1234567
经过 属性动画对View
位置对改变orm
int w = text.getWidth(); int screenW = UiUtil.getScreenWidth(); int transX = screenW - w; ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);1234
使用v4包中的ViewDragHelper
能很好的实现View
的滑动和事件分发,典型谷歌官方的 Drawerlayout
事件