View的坐标系以及X、rawX、translationX、scrollX的区别

转自: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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

(当然用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();
  • 1
  • 2
  • 3

如果采用上面的方式,translationX和translationY依旧是0,但是left会发生变化,这说明直接上面的做法是直接改变了view的位置,并非是平移。那么什么时候才能出现translationX不为0的时候?

方法二:

都说动画实际并不能改变View的位置,甚至连响应事件都不能移动。当然这个相应事件的问题在属性动画时解决掉了,那就来试试用属性动画会产生什么效果。

log(...);
ObjectAnimator.ofFloat(button, "translationX", 0, 100).setDuration(2000).start();
handler.sendEmptyMessageDelayed(1, 3000);
  • 1
  • 2
  • 3

在动画开始前记录下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!不要混淆。



你可能感兴趣的:(android)