android如何安排视图?

时间:2018-10-08 21:40:37

标签: android-layout android-view android-screen-support

我试图了解当我使用setX和setY动态更改视图位置时会发生什么,android转换这些值并特别以不同设备屏幕密度放置视图的过程是什么,因为显然从我的经验来看,视图并没有移到完全相同的 Y 坐标上,我什至试图将Y()设置为常数,但结果始终存在偏移。

我创建了一个仅用于测试的新项目,这是xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relativeLayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layoutDirection="ltr"
>
<TextView
android:id="@+id/move_me"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Move this!"
android:layout_alignParentBottom="true"/>
<TextView
    android:id="@+id/here_to_stay"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="Here!"
    />
<Button
    android:id="@+id/location_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Change Location"
    android:layout_centerHorizontal="true"/>

    </RelativeLayout>

这是java文件:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity {
private final String CONTEXT = "MainActivity";
//define view variables
TextView moveThisTxtView;
TextView hereToStayTxtView;

Button changeLocationBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.activity_main );

    moveThisTxtView = (TextView)findViewById( R.id.move_me );
    hereToStayTxtView = (TextView)findViewById( R.id.here_to_stay );
    changeLocationBtn = (Button)findViewById( R.id.location_btn );


    changeLocationBtn.setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //get view position
            int[] textViewLocation = new int[2];
            int[] oldLocation = new int[2];
            moveThisTxtView.getLocationOnScreen( oldLocation );
            int oldPosX = oldLocation[0];
            int oldPosY = oldLocation[1];
            hereToStayTxtView.getLocationOnScreen( textViewLocation );
            final int targerPosX = textViewLocation[0];
            final int targetPosY = textViewLocation[1];
            Log.v(CONTEXT, "the here to stay x and y are:" + targerPosX + 
            ", " + targetPosY);
            Log.v(CONTEXT, "the view old x and y are:" + oldPosX+ ", " + 
             oldPosY);

            moveThisTxtView.setX(targerPosX);

            moveThisTxtView.setY(targetPosY);

        }
    } );


   }

@Override
public void onWindowFocusChanged (boolean hasFocus) {
    int[] newLocation = new int[2];
    moveThisTxtView.getLocationOnScreen( newLocation );
    int newPosX = newLocation[0];
    int newPosY = newLocation[1];
    Log.v(CONTEXT, "the new x and y are:" + newPosX + ", " + newPosY);
}
}

我不知道为什么,但是我只对y坐标有问题,在所有设备中x总是正确的,我什至不需要将其除以密度,即使在mdp设备中,y总是错误的。这使我问一个问题,这一切如何工作?

1 个答案:

答案 0 :(得分:1)

像素是显示器上单个的光点。正如您所说,视图不会总是移动到显示器中的同一位置,因为不同的显示器具有不同的像素密度。例如,新的iPhone Xr因像素密度太低而受到嘲笑。这是一个巨大的屏幕,但只有720p。

设置位置,高度,宽度和其他尺寸属性时,应使用与密度无关的像素(dp)作为度量单位。使用dp应该可以让您在任何设备上以相同的方式显示视图。

在您的情况下,您想动态更改位置,但是无法在Java中定义dp。为此,您可以在dimens.xml下创建具有以下内容的res/values

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="my_dimen">48dp</dimen>
</resources>

然后您可以使用getResources().getDimension(R.dimen.my_dimen)

引用此值