在RelativeLayout中以编程方式为视图设置边距时,如何解释这种奇怪的行为



我在一个片段中有一个RelativeLayout,它是TabView中三个选项卡之一。看到这个屏幕截图-粉红色的大正方形是我的亲戚布局:屏幕截图

里面的景色是右下角的蓝色小正方形。由于RelativeLayout是300x300pp,小方块是8x8dp,如果我将其顶部和左侧边距设置为292dp,它最终会出现在那个角落。现在我想以编程方式更改它的位置,但当我这样做时,我的值总是被二除。因此,如果我将边距从292更改为292,它最终会在RelativeLayout的中心,但如果我将每个边距设置为292*2,它最终又会回到角落。也许有人知道这里发生了什么?

这是我的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="40dp"
android:height="40dp"
android:background="@color/colorAccent"
android:text="Test!" />
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:background="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:id="@+id/position_dot"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="@color/colorPrimary"
android:layout_marginLeft="292dp"
android:layout_marginTop="292dp"/>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
</layout>

这就是我用来更新边距的方法:

fun moveDotToCurrentPosition() {
var params = positionDot.layoutParams as RelativeLayout.LayoutParams
params.topMargin = 292
params.leftMargin = 292

positionDot.layoutParams = params
}

我试着把代码写得简短,只限于相关的内容,如果缺少重要的内容,请告诉我,我会把它放进去。我用Kotlin写这篇文章,但Java的答案也会很有帮助。非常感谢。

几乎所有只是原始intfloat的Java代码维度值都使用px单元,而不是dp。很可能您正在hdpi设备上执行代码。如果是这样的话,你的屏幕密度意味着1dp==2px,这就解释了为什么所有东西看起来都是"除以2"的。

你可以用这样的代码找到你当前的屏幕密度:

float density = [context].getResources().getDisplayMetrics().density;

然后,您可以将任何dp值乘以这个density,得到px值。

或者,如果您正在使用存储为<dimen>资源的维度,则可以调用:

int dimen = [context].getResources().getDimensionPixelSize(R.dimen.my_dimen);

用于更新页边距的值以px大小的为单位

params.topMargin = 292
params.leftMargin = 292

如果你想将它们更改为292dp,你应该加载一个dimen资源或乘以displayMetric密度的值

您可以使用anko-dip功能

fun Context.dip(value: Int): Int = (value * resources.displayMetrics.density).toInt()

您的代码将如下所示:

params.topMargin = dip(292)
params.leftMargin = dip(292)

也许这可以解决你的问题。

最新更新