我试图了解当我使用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总是错误的。这使我问一个问题,这一切如何工作?
答案 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)