Reputation: 5439
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"...
Upvotes: 432
Views: 264817
Reputation: 19632
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)
}
Upvotes: 2
Reputation: 2151
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()
}
Upvotes: 3
Reputation: 2882
Here is a better solution, not involving double conversion from dp to px then px to dp:
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)
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);
Upvotes: 13
Reputation: 14174
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
Upvotes: 973
Reputation: 197
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
Upvotes: 2
Reputation: 47297
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
Upvotes: 14
Reputation: 566
You can use getDimensionPixelOffset() instead of getDimension, so you didn't have to cast to int.
int valueInPixels = getResources().getDimensionPixelOffset(R.dimen.test)
Upvotes: 16
Reputation: 512824
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);
Upvotes: 22
Reputation: 697
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);
Upvotes: 5
Reputation: 72341
The Resource
class also has a method getDimensionPixelSize() which I think will fit your needs.
Upvotes: 19