一、安卓的当前控件移动可以通过: layout
case MotionEvent.ACTION_MOVE: int offsetX = x - mLastX; int offsetY = y - mLastY; layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
如上所示,在View的控件里面的onTouchEvent函数的ACTION_MOVE 对当前的view进行设置getLeft(), getTop() 等函数是当前控件相对父控件的左上角原点的X和Y的位置,具体可以见:https://www.cnblogs.com/czwlinux/p/16986438.html
二、安卓的当前控件移动可以通过:offsetLeftAndRight 和 offsetTopAndBottom
在第一点的时候,在设置layout时候调用了多个函数并对offsetX和offsetY做加法,调用的函数和计算相对比较多;这里提供了这两个方法可以减少计算:相对左右位置的移动和相对上下位置的移动
case MotionEvent.ACTION_MOVE: int offsetX = x - mLastX; int offsetY = y - mLastY; offsetLeftAndRight(offsetX); offsetTopAndBottom(offsetY);
只是调用两个函数,即可实现一中的效果
三、安卓的当前控件移动可以通过:LayoutParams
我们先看如何进行设置该参数
case MotionEvent.ACTION_MOVE: int offsetX = x - mLastX; int offsetY = y - mLastY; ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams(); layoutParams.leftMargin = getLeft() + offsetX; layoutParams.topMargin = getTop() + offsetY; setLayoutParams(layoutParams);
通过设置该参数的方式能够正常移动当前的view,现象跟一和二是一样。但是如果在当前view增加一个button的兄弟节点(即当前view跟button有相同的父节点),然后拖动当前的view发现button也跟着移动了
通过查看getLayoutParams这个函数发现有这么一段描述,通过该描述大概可以知道是该view的父控件对应的所有子空间都会按照该layoutparams进行布局
/** * Get the LayoutParams associated with this view. All views should have * layout parameters. These supply parameters to the <i>parent</i> of this * view specifying how it should be arranged. There are many subclasses of * ViewGroup.LayoutParams, and these correspond to the different subclasses * of ViewGroup that are responsible for arranging their children. */
所以如果只是想移动当前的view,而不移动它的兄弟view则不宜通过该函数
四、安卓的控件拖动可以通过 scrollBy 或者 scrollTo
两者的区别是:
scrollBy是相对当前的位置移动dx和dy的偏移量: scrollBy(dx, dy)
scrollTo是移动到指定的x和y: scrollTo(x, y)
我们用如下的来调用查看具体的表现
case MotionEvent.ACTION_MOVE: int offsetX = x - mLastX; int offsetY = y - mLastY; scrollBy(offsetX, offsetY);
使用如上的函数进行拖动发现view没有进行移动;其实这两个函数移动的是当前View的content所以当前view没有移动是正常
这么说的话应该是要掉用父view的scrollBy,我们来试一下;
((View)getParent()).scrollBy(offsetX, offsetY);
使用如上的调用,当前的view确实移动了,但是却乱动。
我们刚才说这两个函数移动的是当前View的content,那么获取父节点移动的是父节点的content。那么content和当前的view是什么关系呢?
假设content在左上角(0, 0)的位置,view也是在左上角(0, 0)的位置,content移动(10, 10) 像素后,view相对content是像左上角移动了(因为view不动而content向右下角移动了)。content看到什么那么父节点显示的就是什么,所以我们看到view向左上角移动了。既然是往相反的位置移动,那么我们要让view跟随我们需要的方向移动那么就需要进行取反,如下所示
case MotionEvent.ACTION_MOVE: int offsetX = x - mLastX; int offsetY = y - mLastY; ((View)getParent()).scrollBy(-offsetX, -offsetY);
因为是针对整个父节点的content,所以如果view有兄弟view,该兄弟view也会跟随一起移动
五、当我们move完松开手之后希望它回到原来的位置或者其他位置,并且有回弹效果则可以用scroller
我们这里让scroller回弹回原点,如下所示在ACTION_UP的时候执行startScroll
case MotionEvent.ACTION_UP: View viewGroup = (View) getParent(); mScroller.startScroll(viewGroup.getScrollX(), viewGroup.getScrollY(), -viewGroup.getScrollX(), -viewGroup.getScrollY()); invalidate();
注意,这里的这个mScroller只是一个数值类似model,不会做具体的移动操作,需要在computeScroll做具体的操作
@Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { ((View)getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }
如上所示,通过parent的scallTo的方式进行移动,当然也可以用前面介绍的几种移动方式
标签:控件,拖动,安卓,offsetX,offsetY,content,移动,view From: https://www.cnblogs.com/czwlinux/p/16993497.html