如何解释这个怪异的行为,当以编程方式将边距设置为RelativeLayout中的视图?

我有一个在TabView中的三个选项卡之一的片段内的RelativeLayout。 看到这个截图 – 大粉红色方块是我的RelativeLayout: 截图

里面的视图是右下角的小蓝色方块。 由于RelativeLayout是300x300dp,小方块是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的答案也将有所帮助。 谢谢。

几乎所有只是raw intfloat Java代码维度值都使用px单位, 而不是 dp。 这很可能是您在hdpi设备上执行您的代码。 如果是这样,你的屏幕密度意味着1dp == 2px ,这就解释了为什么一切似乎都被“除以2”。

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

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

然后你可以乘以这个density任何dp值来得到px值。

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

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

您用于更新页边距的值为px大小

 params.topMargin = 292 params.leftMargin = 292 

如果您想将其更改为292dp,则应加载维度资源或乘以displayMetric密度的值

您可以使用anko dip功能

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

你的代码如下所示:

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

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