以编程方式将边距设置为 RelativeLayout 内的视图时,如何解释这种奇怪的行为?
How to explain this weird behaviour when programmatically setting margins to a view inside RelativeLayout?
我在 TabView 中的三个选项卡之一的片段中有一个 RelativeLayout。请参阅此屏幕截图 - 大粉红色方块是我的 RelativeLayout:
screenshot
里面的景色就是右下角的蓝色小方块。由于 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 答案也会有所帮助。
谢谢。
几乎所有 Java-代码维度值只是原始 int
或 float
使用 px 单位,不是 dp。您很可能正在 hdpi 设备上执行代码。如果是这样,您的屏幕密度意味着 1dp
== 2px
,这可以解释为什么一切看起来都是 "divided by 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)
也许这可以解决您的问题。
我在 TabView 中的三个选项卡之一的片段中有一个 RelativeLayout。请参阅此屏幕截图 - 大粉红色方块是我的 RelativeLayout: screenshot
里面的景色就是右下角的蓝色小方块。由于 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 答案也会有所帮助。 谢谢。
几乎所有 Java-代码维度值只是原始 int
或 float
使用 px 单位,不是 dp。您很可能正在 hdpi 设备上执行代码。如果是这样,您的屏幕密度意味着 1dp
== 2px
,这可以解释为什么一切看起来都是 "divided by 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)
也许这可以解决您的问题。