435

I'd like to load the value as it is. I have two dimension.xml files, one in /res/values/dimension.xml and the other one in /res/values-sw360dp/dimension.xml.

From source code I'd like to do something like

getResources().getDimension(R.dimen.tutorial_cross_marginTop);

This works but the value I get is multiplied times the screen density factor (1.5 for hdpi, 2.0 for xhdpi, etc).

I also tried to do

getResources().getString(R.dimen.tutorial_cross_marginTop);

This would work in principle but I get a string that ends in "dip"...

Vadim Kotov
8,2848 gold badges51 silver badges63 bronze badges
asked Jun 20, 2012 at 13:44
2
  • 1
    I wonder if it is bug in Android as Resources has method getDimensionPixelSize(int id) that exactly states that it returns in Pixel, so getDimension(int id) should return in dp (dependency independent units), that would be ready for use, e.g. with View setPadding Commented Sep 12, 2014 at 9:24
  • @PaulVerest I was also puzzled by that redundancy in the API but since it's 2022 and the API documentation states that all methods return "pixels", I imagine it's expected behaviour. Commented Sep 23, 2022 at 13:51

11 Answers 11

975

In my dimens.xml I have

<dimen name="test">48dp</dimen>

In code If I do

int valueInPixels = (int) getResources().getDimension(R.dimen.test)

this will return 72 which as docs state is multiplied by density of current phone (48dp x 1.5 in my case)

exactly as docs state :

Retrieve a dimensional for a particular resource ID. Unit conversions are based on the current DisplayMetrics associated with the resources.

so if you want exact dp value just as in xml just divide it with DisplayMetrics density

int dp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().density);

dp will be 48 now

Alireza Noorali
3,2634 gold badges37 silver badges88 bronze badges
answered Apr 29, 2013 at 10:27
Sign up to request clarification or add additional context in comments.

5 Comments

I think the documentation is particularly unclear here. "Unit conversions are based on the current DisplayMetrics associated with the resources." when all they want to say is that they convert to pixels.
If you are essentially going to be discarding the display metrics multiplier, you may as well just define your dimension in px. <dimen name="test">48px</dimen>. getDimension(R.dimen.test) will return 48.
@Trilarion They do not simply convert to pixels, though. They are saying that dp will give the scaled pixel value relative to the scale of the resource object used to retrieve it. Once you get into various ways to obtain resources, this will be more relevant. For simplicity, you can think of it as being relative to screen scale. There is also sp, or pixels relative to the system text size, and px, or pixels directly. Each is different and has a different purpose.
If you want sp value from dimens.xml, then you'll need int sp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().scaledDensity)
24
Context.getResources().getDimension(int id);
answered Jun 20, 2012 at 13:47

Comments

22

For those who just need to save some int value in the resources, you can do the following.

integers.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <integer name="default_value">100</integer>
</resources> 

Code

int defaultValue = getResources().getInteger(R.integer.default_value);
answered Oct 25, 2017 at 3:10

2 Comments

Thank you for this, was more of what I was looking for even though maybe not for others, but this solution provided actually provided me with some insight into other areas of my code
works like a charm for magic numbers
19

The Resource class also has a method getDimensionPixelSize() which I think will fit your needs.

answered Jun 20, 2012 at 13:48

2 Comments

This is wrong! the metrics conversion also does occurs in getDimensionPixelSize() if you can refer the docs it clearly states Returns Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
This is wrong. The metrics conversion occurs using this method as well.
16

You can use getDimensionPixelOffset() instead of getDimension, so you didn't have to cast to int.

int valueInPixels = getResources().getDimensionPixelOffset(R.dimen.test)
Eric Aya
70.2k36 gold badges190 silver badges266 bronze badges
answered Feb 2, 2018 at 11:16

Comments

14

Use a Kotlin Extension

You can add an extension to simplify this process. It enables you to just call context.dp(R.dimen. tutorial_cross_marginTop) to get the Float value

fun Context.px(@DimenRes dimen: Int): Int = resources.getDimension(dimen).toInt()
fun Context.dp(@DimenRes dimen: Int): Float = px(dimen) / resources.displayMetrics.density

If you want to handle it without context, you can use Resources.getSystem():

val Int.dp get() = this / Resources.getSystem().displayMetrics.density // Float
val Int.px get() = (this * Resources.getSystem().displayMetrics.density).toInt()

For example, on an xhdpi device, use 24.dp to get 12.0 or 12.px to get 24

answered Jan 9, 2020 at 9:09

Comments

13

Here is a better solution, not involving double conversion from dp to px then px to dp:

In Kotlin

fun Resources.getRawDimensionInDp(@DimenRes dimenResId: Int): Float {
 val value = TypedValue()
 getValue(dimenResId, value, true)
 return TypedValue.complexToFloat(value.data)
}
// Usage: 
resources.getRawDimensionInDp(R.dimen.my_dimen_id)

In Java

public class ResourcesUtil {
 static Float getRawDimensionInDp(Resources resources, @DimenRes int dimenResId) {
 TypedValue value = new TypedValue();
 resources.getValue(dimenResId, value, true);
 return TypedValue.complexToFloat(value.data);
 }
}
// Usage: 
ResourcesUtil.getRawDimensionInDp(resources, R.dimen.my_dimen_id);
answered Aug 24, 2021 at 14:50

Comments

5

You can write integer in xml file also..
have you seen [this] http://developer.android.com/guide/topics/resources/more-resources.html#Integer ? use as .

 context.getResources().getInteger(R.integer.height_pop);
answered Nov 7, 2013 at 5:23

Comments

3

Two helper functions I wrote in kotlin for this

/**
 * Gets the float value defined in dimens
 * Define float value as following
 * Example:
 * <item name="example" format="float" type="dimen">1.0</item>
 */
fun Resources.getFloatDimension(dimensResourceId: Int): Float {
 val outValue = TypedValue()
 this.getValue(dimensResourceId, outValue, true)
 return outValue.float
}
/**
 * Gets the dp value defined in dimens
 * Example:
 * <dimen name="example">12dp</dimen>
 *
 * Will return 12
 */
fun Resources.getDimensionInDp(dimensResourceId: Int): Int {
 return (getDimension(dimensResourceId) / displayMetrics.density).toInt()
}
answered Jun 1, 2022 at 19:15

Comments

2

If you just want to change the size font dynamically then you can:

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.tutorial_cross_marginTop))

As @achie's answer, you can get the dp from dimens.xml like this:

val dpValue = (resources.getDimension(R.dimen.tutorial_cross_marginTop)/ resources.displayMetrics.density).toInt()

or get sp like this

val spValue = (resources.getDimension(R.dimen.font_size)/ resources.displayMetrics.scaledDensity).toInt()

About Resources.java #{getDimension}

 /**
 * Retrieve a dimensional for a particular resource ID. Unit 
 * conversions are based on the current {@link DisplayMetrics} associated
 * with the resources.
 * 
 * @param id The desired resource identifier, as generated by the aapt
 * tool. This integer encodes the package, type, and resource
 * entry. The value 0 is an invalid identifier.
 * 
 * @return Resource dimension value multiplied by the appropriate 
 * metric.
 * 
 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
 *
 * @see #getDimensionPixelOffset
 * @see #getDimensionPixelSize
 */

Resource dimension value multiplied by the appropriate

answered Nov 10, 2020 at 7:01

Comments

2

Kotlin:

// Activity
val pixels: Float = resources.getDimension(R.dimen.your_dimen_id)
// Fragment
val pixels: Float = (activity as? MainActivity)?.resources?.getDimension(R.dimen.your_dimen_id) ?: return

Afterwards, if you need to convert Pixels to DP:

fun convertPixelsToDp(px: Float, context: Context): Float {
 return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
answered Nov 22, 2023 at 10:54

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.