View 的getX、getLeft、getTranslationX、getScrollX、offsetLeftAndRight含义分析

View 的getX、getLeft、getTranslationX、getScrollX、offsetLeftAndRight 含义分析

参考https://blog.csdn.net/tanktu/article/details/12752747
getLeft 是子view相对于父组件的坐标位置,是layout的位置;
offsetLeftAndRight是指layout时的偏移量,这个值会直接影响getLeft的值;
getTranslationX 是指view的偏移量,这个值没有改变view的实际位置,点击事件等还是在原来的位置,只是改变了显示位置;
getX = getLeft + getTranslationX,获得当前视图在父容器的x坐标值;
getScrollX 我们使用scroller来动画改变View的ScrollX,ScrollY的时候,组件相对于父组件的位置其实是不变的,改变的是组建内部内容相对于View的位置,对于TextView来说内容是它的文字,对于ViewGroup来说是子组件,因为改变Scroll的值会导致传递的Canvas的原点位置的迁移,改变ViewGroup的scrollX,ScrollY,导致传递到所有的子View的canvas的原点的改变。

另外触摸事件中会传递MotionEvent ev,其中的
ev.getX() ,ev.getY() 是触摸点相对于当前View左上点的相对位置,
ev.getRawx(), ev.getRawY是触摸点相对于屏幕的绝对位置

这里我们写个demo测试下:

布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:text="Btn1"/>
<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_toLeftOf="@id/btn1"
    android:text="Btn2"/>
<TextView
    android:id="@+id/text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="100px"
    android:layout_marginTop="100px"
    android:background="#000000"
    android:textColor="#FFFFFF"
    android:textSize="30dp"
    android:text="Hello World!" />

测试代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button mBtn1;
private Button mBtn2;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTextView = this.findViewById(R.id.text_view);
    mBtn1 = this.findViewById(R.id.btn1);
    mBtn1.setOnClickListener(this);
    mBtn2 = this.findViewById(R.id.btn2);
    mBtn2.setOnClickListener(this);

    printViewLog(mTextView);
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn1:
            printViewLog(mTextView);
            mTextView.setTranslationX(100f);
            printViewLog(mTextView);
            break;
        case R.id.btn2:
            printViewLog(mTextView);
            mTextView.setScrollX(50);
            printViewLog(mTextView);
            break;
    }


}

private void printViewLog(View view) {
    int getLeft = view.getLeft();
    float getX = view.getX();
    float getTranslationX = view.getTranslationX();
    int getScrollX = view.getScrollX();
    Log.v("test", "getLeft = " + getLeft + ", getX = " + getX + ", getScrollX:" + getScrollX + ", getTranslationX:" + getTranslationX);
}
  1. 由于onCreate方法执行时还未完成布局,我们添加了两个按钮来打印log,启动后初始状态界面如图
    在这里插入图片描述
    打印出:
    V test : getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0

可以看出onCreate时view的位置还未按照布局进行layout,坐标值都是0。

  1. 点击BTN1,打印出 mTextView.setTranslationX(100f) 前后各参数值

在这里插入图片描述
打印出:
V test : getLeft = 100, getX = 100.0, getScrollX:0, getTranslationX:0.0
V test : getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0
3. 继续点击BTN2,打印出 mTextView.setScrollX(50) 前后的值:
在这里插入图片描述
打印出:
V test : getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0
V test : getLeft = 100, getX = 200.0, getScrollX:50, getTranslationX:100.0

可以看出ScrollX改变了TextView绘制内容canvas的坐标,setScrollX(50)相当于TextView中的画布偏移了50像素,只绘制出右侧的部分内容出来。

上面说scrollX改变的是组件内部内容相对于View的位置,对于TextView来说内容是它的文字,对于ViewGroup来说是子组件,这里我们再测试下子组件的情况:

布局文件main.xml 稍微改了下,给TextView套了个父控件

<?xml version="1.0" encoding="utf-8"?>

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentBottom="true"
    android:text="Btn1" />

<Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_toLeftOf="@id/btn1"
    android:text="Btn2" />

<RelativeLayout
    android:id="@+id/view_group"
    android:layout_width="800px"
    android:layout_height="800px"
    android:background="#0000ff">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100px"
        android:layout_marginTop="100px"
        android:background="#000000"
        android:text="Hello World!"
        android:textColor="#FFFFFF"
        android:textSize="30dp" />
</RelativeLayout>

测试代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button mBtn1;
private Button mBtn2;
private TextView mTextView;
private RelativeLayout mViewGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTextView = this.findViewById(R.id.text_view);
    mViewGroup = this.findViewById(R.id.view_group);
    mBtn1 = this.findViewById(R.id.btn1);
    mBtn1.setOnClickListener(this);
    mBtn2 = this.findViewById(R.id.btn2);
    mBtn2.setOnClickListener(this);

    printViewLog(mViewGroup);
    printViewLog(mTextView);
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn1:
            printViewLog(mViewGroup);
            printViewLog(mTextView);
            mTextView.setTranslationX(100f);
            printViewLog(mViewGroup);
            printViewLog(mTextView);
            break;
        case R.id.btn2:
            printViewLog(mViewGroup);
            printViewLog(mTextView);
            mViewGroup.setScrollX(50);
            printViewLog(mViewGroup);
            printViewLog(mTextView);
            break;
    }


}

private void printViewLog(View view) {
    int getLeft = view.getLeft();
    float getX = view.getX();
    float getTranslationX = view.getTranslationX();
    int getScrollX = view.getScrollX();
    Log.v("test", view.getClass().getSimpleName() + " getLeft = " + getLeft + ", getX = " + getX + ", getScrollX:" + getScrollX + ", getTranslationX:" + getTranslationX);
}

}

  1. onCreate后的初始界面及log
    在这里插入图片描述
    V test : RelativeLayout getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0

  2. 点击BTN1后的界面显示及log
    在这里插入图片描述
    V test : RelativeLayout getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 100, getX = 100.0, getScrollX:0, getTranslationX:0.0
    V test : RelativeLayout getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0

  3. 继续点击BTN2后的界面显示及log
    在这里插入图片描述
    V test : RelativeLayout getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0
    V test : RelativeLayout getLeft = 0, getX = 0.0, getScrollX:50, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0

可以看出父控件设置scrollX后并没有影响子控件的getX和getTranslationX,但是影响了子控件的显示位置。

下面再测试下offsetLeftAndRight属性的影响,布局文件还是同上,只是在BTN2点击时代码稍微改动:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button mBtn1;
private Button mBtn2;
private TextView mTextView;
private RelativeLayout mViewGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTextView = this.findViewById(R.id.text_view);
    mViewGroup = this.findViewById(R.id.view_group);
    mBtn1 = this.findViewById(R.id.btn1);
    mBtn1.setOnClickListener(this);
    mBtn2 = this.findViewById(R.id.btn2);
    mBtn2.setOnClickListener(this);

    printViewLog(mTextView);
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn1:
            Log.v("wang", "BTN1 clicked");
            printViewLog(mTextView);
            mTextView.setTranslationX(100f);
            printViewLog(mTextView);
            this.startService(new Intent(this, MyService.class));
            break;
        case R.id.btn2:
            Log.v("wang", "BTN2 clicked");
            printViewLog(mTextView);
            mTextView.offsetLeftAndRight(50);
            printViewLog(mTextView);
            break;
    }


}

private void printViewLog(View view) {
    int getLeft = view.getLeft();
    float getX = view.getX();
    float getTranslationX = view.getTranslationX();
    int getScrollX = view.getScrollX();
    Log.v("test", view.getClass().getSimpleName() + " getLeft = " + getLeft + ", getX = " + getX + ", getScrollX:" + getScrollX + ", getTranslationX:" + getTranslationX);
}

}

  1. 启动初始界面及log
    在这里插入图片描述
    V test : AppCompatTextView getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
  2. 点击BTN1后的界面及log
    在这里插入图片描述
    V test : AppCompatTextView getLeft = 100, getX = 100.0, getScrollX:0, getTranslationX:0.0
    V test : AppCompatTextView getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0
  3. 继续点击BTN2后的界面及log
    在这里插入图片描述
    V test : AppCompatTextView getLeft = 100, getX = 200.0, getScrollX:0, getTranslationX:100.0
    V test : AppCompatTextView getLeft = 150, getX = 250.0, getScrollX:0, getTranslationX:100.0

可以看出执行 mTextView.offsetLeftAndRight(50)后,getLeft的值增加了50,也就是影响了layout的参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值