Conversión de píxeles a dp

He creado mi aplicación con el alto y ancho dados en píxeles para un dispositivo Pantech cuya resolución es 480×800.

Necesito convertir la altura y el ancho para un dispositivo G1. Pensé que convertirlo en dp resolvería el problema y proporcionaría la misma solución para ambos dispositivos.

¿Hay alguna manera fácil de convertir píxeles a dp? ¿Alguna sugerencia?

 // Converts 14 dip into its equivalent px float dip = 14f; Resources r = getResources(); float px = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dip, r.getDisplayMetrics() ); 
 /** * This method converts dp unit to equivalent pixels, depending on device density. * * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels * @param context Context to get resources and device specific display metrics * @return A float value to represent px equivalent to dp depending on device density */ public static float convertDpToPixel(float dp, Context context){ Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); return px; } /** * This method converts device specific pixels to density independent pixels. * * @param px A value in px (pixels) unit. Which we need to convert into db * @param context Context to get resources and device specific display metrics * @return A float value to represent dp equivalent to px value */ public static float convertPixelsToDp(float px, Context context){ return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); } 

Preferiblemente poner en una clase Util.java

 public static float dpFromPx(final Context context, final float px) { return px / context.getResources().getDisplayMetrics().density; } public static float pxFromDp(final Context context, final float dp) { return dp * context.getResources().getDisplayMetrics().density; } 
 float density = context.getResources().getDisplayMetrics().density; float px = someDpValue * density; float dp = somePxValue / density; 

density es igual

  • .75 en ldpi ( 120 dpi)
  • 1.0 en mdpi ( 160 ppp, línea base)
  • 1.5 en hdpi ( 240 dpi)
  • 2.0 en xhdpi ( 320 dpi)
  • 3.0 en xxhdpi ( 480 dpi)
  • 4.0 en xxxhdpi ( 640 dpi)

Use este convertidor en línea para jugar con valores de ppp.

EDITAR: Parece que no hay una relación 1: 1 entre el cubo dpi y la density . Parece que el Nexus 5X siendo xxhdpi tiene un valor de density de 2.625 (en lugar de 3 ). Véalo usted mismo en Device Metrics .

De acuerdo con la Guía de desarrollo de Android:

 px = dp * (dpi / 160) 

Pero a menudo querrás hacer esto al revés cuando recibas un diseño expresado en píxeles. Asi que:

 dp = px / (dpi / 160) 

Si está en un dispositivo de 240 ppp, esta relación es 1.5 (como se indicó anteriormente), por lo que significa que un icono de 60 píxeles equivale a 40 pb en la aplicación.

¡Si puede usar las dimensiones XML, es muy simple!

En su res/values/dimens.xml :

   120dp ... ...  

Luego en tu Java:

 getResources().getDimensionPixelSize(R.dimen.thumbnail_height); 

Sin Context , métodos estáticos elegantes:

 public static int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } public static int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); } 

Puedes usar esto … sin contexto

 public static int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); } public static int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } 

Para DP to Pixel

Crea un valor en dimens.xml

 20dp 

Obtenga ese valor en pixel como:

 int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize); 

Por lo tanto, puede usar el siguiente formulador para calcular la cantidad correcta de píxeles desde una dimensión especificada en dp

 public int convertToPx(int dp) { // Get the screen's density scale final float scale = getResources().getDisplayMetrics().density; // Convert the dps to pixels, based on density scale return (int) (dp * scale + 0.5f); } 

Hay una utilidad predeterminada en el SDK de Android: http://developer.android.com/reference/android/util/TypedValue.html

 float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics()) 

Para cualquiera que use Kotlin:

 val Int.toPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt() val Int.toDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt() 

Uso:

 64.toPx 32.toDp 

Esto debería darle la conversión dp a píxeles:

 public static int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } 

Esto debería darle los píxeles de conversión a dp:

 public static int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); } 

Para convertir dp en pixel.

 public static int dp2px(Resources resource, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics()); } 

Para convertir píxeles a dp.

  public static float px2dp(Resources resource, float px) { return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics()); } 

donde el recurso es context.getResources ().

Probablemente la mejor manera si tiene la dimensión dentro de valores / dimen es obtener la dimensión directamente desde el método getDimension (), le devolverá la dimensión ya convertida en valor de píxel.

 context.getResources().getDimension(R.dimen.my_dimension) 

Solo para explicar mejor esto,

 getDimension(int resourceId) 

devolverá la dimensión ya convertida a píxel COMO UNA FLOTACIÓN.

 getDimensionPixelSize(int resourceId) 

devolverá lo mismo pero truncado a int, entonces AS AN INTEGER.

Ver la referencia de Android

Me gusta esto:

 public class ScreenUtils { public static float dpToPx(Context context, float dp) { if (context == null) { return -1; } return dp * context.getResources().getDisplayMetrics().density; } public static float pxToDp(Context context, float px) { if (context == null) { return -1; } return px / context.getResources().getDisplayMetrics().density; } } 

Depende de Contexto, valor de flotación de retorno, método estático

desde: https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15

En caso de que desarrolle una aplicación crítica para el rendimiento, considere la siguiente clase optimizada:

 public final class DimensionUtils { private static boolean isInitialised = false; private static float pixelsPerOneDp; // Suppress default constructor for noninstantiability. private DimensionUtils() { throw new AssertionError(); } private static void initialise(View view) { pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f; isInitialised = true; } public static float pxToDp(View view, float px) { if (!isInitialised) { initialise(view); } return px / pixelsPerOneDp; } public static float dpToPx(View view, float dp) { if (!isInitialised) { initialise(view); } return dp * pixelsPerOneDp; } } 
 float scaleValue = getContext().getResources().getDisplayMetrics().density; int pixels = (int) (dps * scaleValue + 0.5f); 

Así es como funciona para mí:

 DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int h = displaymetrics.heightPixels; float d = displaymetrics.density; int heightInPixels=(int) (h/d); 

Puedes hacer lo mismo por el ancho.

Deberías usar dp como lo harías con los píxeles. Eso es todo lo que son; mostrar píxeles independientes. Use los mismos números que usaría en una pantalla de densidad media, y el tamaño será mágicamente correcto en una pantalla de alta densidad.

Sin embargo, parece que lo que necesita es la opción fill_parent en su diseño de diseño. Use fill_parent cuando desee que su vista o control se expanda a todo el tamaño restante en el contenedor primario.

para convertir píxeles a dp use TypedValue .

Como se menciona en la documentación: Contenedor para un valor de datos tipeado dinámicamente.

y use el método applyDimension :

 public static float applyDimension (int unit, float value, DisplayMetrics metrics) 

que convierte un valor de datos complejo sin empaquetar que contiene una dimensión en su valor de punto flotante final como el siguiente:

 Resources resource = getResources(); float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics()); 

Espero que ayude .

Enfoque más elegante usando la función de extensión de Kotlin

 /** * Converts dp to pixel */ val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt() /** * Converts pixel to dp */ val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt() 

Uso:

 println("16 dp in pixel: ${16.dpToPx}") println("16 px in dp: ${16.pxToDp}") 

Muchas soluciones geniales arriba. Sin embargo, la mejor solución que encontré es el diseño de Google:

https://design.google.com/devices/

Densidad

PX y DP son diferentes pero similares.

DP es la resolución cuando solo factoriza el tamaño físico de la pantalla. Cuando usa DP escalará su diseño a otras pantallas de tamaño similar con diferentes densidades de pixel .

Ocasionalmente, en realidad quiere pixels , y cuando maneja dimensiones en el código, siempre trata con pixels reales, a menos que los convierta.

Por lo tanto, en un dispositivo Android, una pantalla hdpi tamaño normal, 800x480 is 533x320 en DP (creo). Para convertir DP en pixels /1.5 , para convertir de nuevo *1.5 . Esto es solo para el tamaño de una pantalla y dpi , cambiaría según el diseño. Sin embargo, nuestros artistas me dan pixels y yo convierto a DP con la ecuación 1.5 anterior.

Esto funciona para mí (C #):

 int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f); 

Si quiere valores enteros , usar Math.round () redondeará el float al entero más cercano.

 public static int pxFromDp(final float dp) { return Math.round(dp * Resources.getSystem().getDisplayMetrics().density); } 

Para convertir dp to px este código puede ser útil:

 public static int dpToPx(Context context, int dp) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); }