Reputation: 1115
I have a RelativeLayout inside a fragment that one of three tabs in a TabView. See this Screenshot - big pink square is my RelativeLayout: screenshot
The view that is inside it is the little blue square in the bottom right corner. Since the RelativeLayout is 300x300dp and the little square is 8x8dp, if I set its top and left margin to 292dp it ends up in that corner. Now I want to change its position programmatically, but when I do it, my values keep getting divided by two. So if I change the margins from 292 to 292 it ends up in the center of the RelativeLayout, but if I set each to 292*2, it ends up back in the corner. Maybe there is someone who knows what is happening here?
This is my layout file:
<?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>
and this is the method I use to update the margins:
fun moveDotToCurrentPosition() {
var params = positionDot.layoutParams as RelativeLayout.LayoutParams
params.topMargin = 292
params.leftMargin = 292
positionDot.layoutParams = params
}
I tried to keep the code short and limited to what's relevant, if something important is missing please let me know and I put it in. I'm writing this one in Kotlin, but Java answers will be helpful too. Thank you.
Upvotes: 0
Views: 48
Reputation: 2636
The values you are using to update your margins are in px size
params.topMargin = 292
params.leftMargin = 292
If you want to change them to 292dp you should load a dimen resource or multiply the value for displayMetric density
You can use the anko dip function
fun Context.dip(value: Int): Int = (value * resources.displayMetrics.density).toInt()
Your code will look like this:
params.topMargin = dip(292)
params.leftMargin = dip(292)
Maybe this can fix your issue.
Upvotes: 0
Reputation: 54204
Almost all Java-code dimension values that are just raw int
or float
use px units, not dp. It is very likely that you are executing your code on an hdpi device. If so, your screen density means that 1dp
== 2px
, and this would explain why everything seems to be "divided by 2".
You can find your current screen density with code like this:
float density = [context].getResources().getDisplayMetrics().density;
And you can then multiply any dp
values by this density
to get the px
values.
Alternatively, if you're working with dimensions that you've stored as <dimen>
resources, you can just call:
int dimen = [context].getResources().getDimensionPixelSize(R.dimen.my_dimen);
Upvotes: 1