转自:http://blog.csdn.net/whsdu929/article/details/52152520
http://blog.csdn.net/wxv111/article/details/50901199
简单介绍一下View的坐标系:
view的位置由left、top、right、bottom四个属性决定,这几个坐标可以通过getLeft()、getTop()、getRight()、getBottom()获取。注意这四个坐标是相对坐标,即相对于父容器的坐标。当view发生移动时,这几个坐标是不变的。
从Android 3.0开始,增加了几个参数:x、y、translationX、translationY,都是相对于父容器的坐标。
x指view左上角的横坐标,当view发生移动时,x会变化;
translationX指view左上角的横坐标相对于父容器的偏移量,当view发生移动时,translationX会变化。
有关系式 x = left + translationX 成立。
rawX是绝对坐标,是相对于屏幕左上角的横坐标,view本身没有getRawX的方法,这个方法一般在MotionEvent对象里使用。
scrollX指的是view在滑动过程中,view的左边缘和view内容的左边缘在水平方向的距离(注意与translationX 的区别,translationX 指的是view本身的移动,scrollX是view的内容移动),也就是说调用了view的scrollTo或scrollBy方法,view本身不会移动,只会移动view的内容。
下图仅供理解(需要注意scrollX与translationX 的区别):
*****************************************************************************
在上一篇文章View的位置中,介绍了top, left, bottom, right这几个坐标,我们知道了这几个坐标是view与其所在的父容器的相对位置。那x,y,translationX,translationY是做什么的?这几个坐标是在Android API 11(Android3.0)之后加进来的。
还是之前的那个例子
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/block1"
android:layout_width="match_parent"
android:layout_height="200px"
android:background="@color/blue"/>
<RelativeLayout
android:id="@+id/block2"
android:layout_below="@+id/block1"
android:layout_width="match_parent"
android:layout_height="2000px"
android:background="@color/red">
<Button
android:id="@+id/button"
android:layout_width="250px"
android:layout_height="100px"
android:layout_marginLeft="30px"
android:layout_marginTop="30px"
android:text="button"/>
RelativeLayout>
RelativeLayout>
(当然用px
在xml里是绝对不推荐,但是为了这次log能够看的清楚写的测试程序)
那么打出log看一看这几个控件的实际位置:
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ button, top:30,left:30:bottom:130,right:280
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ button, x:30.0,y:30.0:translationX:0.0,translationY:0.0
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ block1, top:0,left:0:bottom:200,right:720
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ block1, x:0.0,y:0.0:translationX:0.0,translationY:0.0
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ block2, top:200,left:0:bottom:1118,right:720
03-16 00:02:41.607 4442-4442/com.example.sakuraisho.scrollapp V/position﹕ block2, x:0.0,y:200.0:translationX:0.0,translationY:0.0
先给出结论,View在平移的过程中,top和left表示的是原始左上角的位置信息,其值不会发生改变。而在平移过程中发生改变的是x,y,translationX,translationY。x,y是View左上角的坐标,translationX,translationY是平移的距离。即
x = left + translationX
y = top + translationY
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams();
params.leftMargin +=300;
button.requestLayout();
如果采用上面的方式,translationX和translationY依旧是0,但是left会发生变化,这说明直接上面的做法是直接改变了view的位置,并非是平移。那么什么时候才能出现translationX不为0的时候?
都说动画实际并不能改变View的位置,甚至连响应事件都不能移动。当然这个相应事件的问题在属性动画时解决掉了,那就来试试用属性动画会产生什么效果。
log(...);
ObjectAnimator.ofFloat(button, "translationX", 0, 100).setDuration(2000).start();
handler.sendEmptyMessageDelayed(1, 3000);
在动画开始前记录下button的位置,当动画结束后再记录下位置,如下:
03-16 00:39:49.500 25085-25085/com.example.sakuraisho.scrollapp V/position﹕ button, top:30,left:30:bottom:130,right:280
03-16 00:39:49.500 25085-25085/com.example.sakuraisho.scrollapp V/position﹕ button, x:30.0,y:30.0:translationX:0.0,translationY:0.0
03-16 00:39:52.503 25085-25085/com.example.sakuraisho.scrollapp V/position﹕ after button, top:30,left:30:bottom:130,right:280
03-16 00:39:52.503 25085-25085/com.example.sakuraisho.scrollapp V/position﹕ after button, x:130.0,y:30.0:translationX:100.0,translationY:0.0
惊喜的发现,translationX平移了100,x的值也变为了130,而原始的坐标并没有变化!
突然有点疑惑,View是真正被转移了吗?还是说x,translationX只是一个暂存的状态,否则要原始的坐标left做什么呢?如果button上有点击事件的话,当动画结束后,点击事件能正确响应吗?
经过测试,button在动画中,动画结束后,均能够正确响应点击事件。所以单纯的理解好这几个坐标所代表的意义就好!书上说的什么Adroid3.0以前动画是对View的影像进行操作,不改变View的位置参数宽高等,并不影响坐标的意义!
改变了view的layoutparams就改变了view的原始的坐标。而通过动画改变的位置是会保留原始的坐标。但这并不代表在原位置保存了原始的view!不要混淆。