In my Android application I have pixels(69px) and I need to convert this pixels into dip(Density Independent Pixels).
Any suggestions?
Just divide your value in pixels by DisplayMetrics.density.
Hope this will be helpful
Resources r = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, r.getDisplayMetrics());
You can try this:
public int convertDiptoPx(int pixel){
float scale = getResources().getDisplayMetrics().density;
int dips=(int) ((pixel * scale) + 0.5f);
logMessage("Px=" +pixel+" DipValue="+dips );
return dips;
}
Editted:
public int convertPxtoDip(int pixel){
float scale = getResources().getDisplayMetrics().density;
int dips=(int) ((pixel / scale) + 0.5f);
return dips;
}
Related
I want set margin for views by programmatically, i should set 50dp for margin_top, i use this code
ViewGroup.MarginLayoutParams marginParams = new ViewGroup.MarginLayoutParams(searchView.getLayoutParams());
marginParams.setMargins(0, 75, 0, 0);
CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(marginParams);
searchView.setLayoutParams(layoutParams);
but in this code set 50px! how can i set this 50dp, not px?!
You have to convert it:
final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);
For dimens.xml:
context.getResources().getDimensionPixelSize(R.dimen.view_height);
For harcoded value:
int height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
getContext().getResources().getDisplayMetrics());
public static int dp(int px) {
return (int) (px * Resources.getSystem().getDisplayMetrics().density);
}
int margin = dp(50);
Use this code:
/**
* Convert dp to pixel
*
* #param dp
* #return px
*/
public static int dpToPx(final float dp) {
return Math.round(dp * (Resources.getSystem().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,getResources().getDisplayMetrics());
convert it!
Here's a Kotlin solution
You can use the following function:
fun dpToPx(context: Context, dp: Float): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics).roundToInt()
}
You could choose to take advantage of extensions instead:
// Use: 16f.dpToPx(context)
internal fun Float.dpToPx(context: Context): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics).roundToInt()
}
Or if using a dimens resource, use the following:
context.resources.getDimensionPixelSize(R.dimen.some_dimen_id)
I have a custom action bar which i want a 80ish! height for it.
so i set my layouts height as 80dp with this code:
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
xdpi = displayMetrics.xdpi;
x = Math.round(80 * (xdpi / DisplayMetrics.DENSITY_DEFAULT))
... new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, x);
but its HUGE in xxxhdpi devices.
when i remove the conversion and use 80pixels value directly, it seems ok,
When to use converted dp and when to use direct pixel?
Edit:
the problem was somewhere else, i stored the "80dp" value in xml and retrieve it with "context.getResources().getDimension()", and it seems it converts the dimension to pixel internally and i was actually converting the converted value! I wonder if the same thing happens when using "sp" for fonts....
You're doing the right thing it's just your conversion is wrong, it should be something like this:
float scale = context.getResources().getDisplayMetrics().density;
x = Math.round(80 * scale);
... new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, x);
Convert dp to pixel:
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
Convert pixel to dp:
public int pxToDp(int px) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return dp;
}
Pixel to Dp converter
public static float pxToDp(float px) {
float densityDpi = Resources.getSystem().getDisplayMetrics().densityDpi;
return px / (densityDpi / 160f);
}
Dp to Pixel converter
public static int dpToPx(int dp) {
float density = Resources.getSystem().getDisplayMetrics().density;
return Math.round(dp * density);
}
I had written method to get the pixels from dip but it is not working. It give me runtime error.
Actually I was running this method in separate class and initialized in my Activity class
Board board = new Board(this);
board.execute(URL);
This code runs asynchronously. Please help me.
public float getpixels(int dp){
//Resources r = boardContext.getResources();
//float px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpis, r.getDisplayMetrics());
final float scale = this.boardContext.getResources().getDisplayMetrics().density;
int px = (int) (dp * scale + 0.5f);
return px;
}
Try this:
Java
public static float dipToPixels(Context context, float dipValue) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
}
Kotlin
fun Context.dipToPixels(dipValue: Float) =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, resources.displayMetrics)
You can add the dp value in dimen.xml and use
int pixels = getResources().getDimensionPixelSize(R.dimen.idDimension);
It's easier...
The formula is: px = dp * (dpi / 160), for having on a 160 dpi screen. See Convert dp units to pixel units for more information.
You could try:
public static int convertDipToPixels(float dips) {
return (int) (dips * appContext.getResources().getDisplayMetrics().density + 0.5f);
}
Hope this helps...
Try this for without passing context:
public static float dipToPixels(float dipValue) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dipValue,
Resources.getSystem().getDisplayMetrics()
);
}
Is there any way to set the height/width of a LayoutParams as density-independent pixels (dp)? It looks like the height/width, when set programmatically, are in pixels and not dp.
You need to convert your dip value into pixels:
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());
For me this does the trick.
public static int getDPI(int size, DisplayMetrics metrics){
return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
}
Call the function like this,
DisplayMetrics metrics;
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heigh = getDPI(height or width, metrics);
Since it may be used multiple times:
public static int convDpToPx(Context context, float dp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
I found it more practical to use the conversion rate, as usally more than one value has to be converted. Since the conversion rate does not change, it saves a bit of processing time.
/**
* Get conversion rate from dp into px.<br>
* E.g. to convert 100dp: px = (int) (100 * convRate);
* #param context e.g. activity
* #return conversion rate
*/
public static float convRateDpToPx(Context context) {
return context.getResources().getDisplayMetrics().densityDpi / 160f;
}
Here is my snippet:
public class DpiUtils {
public static int toPixels(int dp, DisplayMetrics metrics) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
}
where DisplayMetrics metrics = getResources().getDisplayMetrics()
The answered solution didn't work for me, the height of the view was still off. I ended up with this, which works well:
protected int dp2px(int dp){
final float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
And if you want the other way round, pixels to dp ...
protected float px2dp(float px){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}
I have an image of a face (250px X 250px) that is in an absolute layout element. I currently get the user's touch coordinates and using some maths calculate what has been touched (eg the nose), then do something accordingly.
My question is how to scale this to fit the screen width available. If I set the image (in the xml) to fill_parent, the coordinates are way out. Can this be remedied by converting the touch coordinates to dips (if so, how), or will I need to get the screen width (again convert into dips) and sort out the coordinate problem using more maths?
Any and all help appreciated.
pixels = dps * (density / 160)
The (density / 160) factor is known as the density scale factor, and get be retrieved in Java from the Display Metrics object. What you should do is store the position of the nose etc in terms of dips (which are the same as pixels on a screen with density 160), and then convert dips to pixels depending on what screen you are running on:
final static int NOSE_POSITION_DP = 10;
final float scale = getContext().getResources().getDisplayMetrics().density;
final int nosePositionPixels = (int) (NOSE_POSITION_DP * scale + 0.5f);
I have three useful functions in my library...
get Screen Density
public static float getDensity(Context context){
float scale = context.getResources().getDisplayMetrics().density;
return scale;
}
convert Dip to Pixels.
public static int convertDiptoPix(int dip){
float scale = getDensity();
return (int) (dip * scale + 0.5f);
}
convert Pixels to Dips.
public static int convertPixtoDip(int pixel){
float scale = getDensity();
return (int)((pixel - 0.5f)/scale);
}
A very simple way of doing this.
int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 250, (mContext).getResources().getDisplayMetrics());
public int getDip(int pixel)
{
float scale = getBaseContext().getResources().getDisplayMetrics().density;
return (int) (pixel * scale + 0.5f);
}