How to convert dp to px in xamarin.android?

12,187

Solution 1

Solution to "First code":

Xamarin tends to move constants into their own enums. COMPLEX_UNIT_DIP can be found on ComplexUnitType enum. Also you cannot have < HEIGHT > in your code you actually need to pass in dips to get the equivalent pixel value. in the example below I am getting pixels in 100 dips.

var dp = 100;
int pixel = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, Context.Resources.DisplayMetrics);

Solution to "Second code":

You need to explicitly cast 'DisplayMetrics.DensityDefault' to a float and the entire round to an int:

int pixel = (int)System.Math.Round(dp * (displayMetrics.Xdpi / (float)DisplayMetrics.DensityDefault));

I prefer the first approach as the second code is specifically for calculating along the "x dimension": Per Android docs and Xamarin.Android docs, the Xdpi property is

"The exact physical pixels per inch of the screen in the X dimension."

Solution 2

These are from the project that I am currently working on..

public static float pxFromDp(Context context, float dp)
{
    return dp * context.Resources.DisplayMetrics.Density;
}

public static float dpFromPx(Context context, float px)
{
    return px / context.Resources.DisplayMetrics.Density;
}
Share:
12,187
Reyhaneh Sharifzadeh
Author by

Reyhaneh Sharifzadeh

Updated on June 05, 2022

Comments

  • Reyhaneh Sharifzadeh
    Reyhaneh Sharifzadeh about 2 years

    I want to convert dp to px in my C# code in xamarin.android, but all I could find were java codes in android studio that have some problems in xamarin. I tried to use equivalent like using Resources instead of getResources() and I could solve some little problems, but there are some problems yet that I couldn't find any equivalent for them. here are original codes, my codes, and my codes problems in xamarin:

    First code

    (found from Programatically set height on LayoutParams as density-independent pixels)

    java code

    int height = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, < HEIGHT >, getResources().getDisplayMetrics());
    

    C# code

    int height = (int)TypedValue.ApplyDimension(TypedValue.COMPLEX_UNIT_DIP, < HEIGHT >, Resources.DisplayMetrics);
    

    problems:

    • 'TypedValue' does not contain a definition for 'COMPLEX_UNIT_DIP'

    • Invalid expression term < (The same error for >)

    • The name 'HEIGHT' does not exist in the current context

    Second code

    (found from Formula px to dp, dp to px android)

    java code

    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    

    C# code

    DisplayMetrics displayMetrics = Application.Context.Resources.DisplayMetrics;
    int pixel = Math.Round(dp * (displayMetrics.Xdpi / DisplayMetrics.DensityDefault));
    

    problem

    • Operator '/' cannot be applied to operands of type 'float' and 'DisplayMetricsDensity'

    Now I have actually two questions. Which code is more proper? What's equivalent code for them in xamarin.android?

    Thanks in advance.

  • Reyhaneh Sharifzadeh
    Reyhaneh Sharifzadeh over 7 years
    The error is still shown. 'DisplayMetricsDensity' couldn't convert to float or int, so I couldn't apply any operator to this operand and an integer or float operand.
  • Reyhaneh Sharifzadeh
    Reyhaneh Sharifzadeh over 7 years
    Yes, I prefer the first one too. the second one doesn't work same on different devices because of what you said and also has a warning: 'DisplayMetrics.DensityDefault' is obsolete: 'This constant will be removed in the future version. Use Android.Util.DisplayMetricsDensity enum directly instead of this field.'
  • matfillion
    matfillion about 7 years
    @ReyhanehSH you can hard cast float to int, or double to float, it will work. Especially since for UI you don't really mind if you are 0.0000000001 pixels off. But anyhow, the accepted answer is more up to date than this one.
  • ethane
    ethane about 7 years
    Pretty easy solution, I am using an adjusted version for Xamarin.Forms (v2.3.4247): var dp= pixels* (int)Resources.System.DisplayMetrics.Density;
  • Saravanakumar Natarajan
    Saravanakumar Natarajan almost 4 years
    @ReyhanehSharifzadeh, I understood the concept, could you please tell me why we need to convert the value to pixel? and the pixel value where we need to set. Thank you
  • Gertjan Brouwer
    Gertjan Brouwer about 3 years
    I use DeviceDisplay.MainDisplayInfo.Density from the Xamarin.Essentials import.