How to convert dp to px in xamarin.android?

2019-06-15 14:59发布

问题:

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.

回答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."



回答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;
}


回答3:

dp to px:

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

Answer taken from here : https://stackoverflow.com/a/8490361/6949388

Sorry, not enough rep to comment.