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);
}
- 由于onCreate方法执行时还未完成布局,我们添加了两个按钮来打印log,启动后初始状态界面如图
打印出:
V test : getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0
可以看出onCreate时view的位置还未按照布局进行layout,坐标值都是0。
- 点击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);
}
}
-
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 -
点击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 -
继续点击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);
}
}
- 启动初始界面及log
V test : AppCompatTextView getLeft = 0, getX = 0.0, getScrollX:0, getTranslationX:0.0 - 点击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 - 继续点击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的参数。