Fórmula px a dp, dp a px android

Estoy tratando de calcular una cantidad variable de píxeles a píxeles independientes de densidad y viceversa.

Esta fórmula (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160)); no funciona en dispositivos pequeños porque está dividido por cero.

Esta es mi fórmula de dp a px:

 px = (int)(dp * (displayMetrics.densityDpi / 160)); 

¿Podría alguien darme algunos consejos?

Nota: La solución ampliamente utilizada anteriormente se basa en displayMetrics.density . Sin embargo, los documentos explican que este valor es un valor redondeado, que se utiliza con la pantalla ‘cubos’. P.ej. en mi Nexus 10 devuelve 2, donde el valor real sería 298 ppp (real) / 160 ppp (predeterminado) = 1.8625.

Dependiendo de sus requisitos, es posible que necesite la transformación exacta, que se puede lograr de esta manera:

[Editar] Esto no está destinado a mezclarse con la unidad de dp interna de Android, ya que, por supuesto, todavía se basa en los segmentos de la pantalla. Use esto donde desee una unidad que debería mostrar el mismo tamaño real en diferentes dispositivos.

Convierta dp a pixel:

 public int dpToPx(int dp) { DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)); } 

Convierta píxel a dp:

 public int pxToDp(int px) { DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)); } 

Tenga en cuenta que existen propiedades xdpi y ydpi, es posible que desee distinguir, pero no puedo imaginar una visualización en la que estos valores difieran mucho.

Resolví mi problema usando las siguientes fórmulas. Que otras personas se beneficien de eso.

dp a px:

 displayMetrics = context.getResources().getDisplayMetrics(); return (int)((dp * displayMetrics.density) + 0.5); 

px a dp:

 displayMetrics = context.getResources().getDisplayMetrics(); return (int) ((px/displayMetrics.density)+0.5); 

px a dp:

 int valueInpx = ...; int valueInDp= (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources() .getDisplayMetrics()); 

Simplemente llame a getResources().getDimensionPixelSize(R.dimen.your_dimension) para convertir de unidades dp a píxeles

Manera eficiente alguna vez

DP a Pixel:

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

Pixel a DP:

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

Espero que esto te ayudará.

Use esta función

 private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } 
 px = dp * (dpi / 160) dp = px * (160 / dpi) 

En la mayoría de los casos, las funciones de conversión se llaman con frecuencia. Podemos optimizarlo agregando memoria. Por lo tanto, no calcula cada vez que se llama a la función.

Declaremos un HashMap que almacenará los valores calculados.

 private static Map pxCache = new HashMap<>(); 

Una función que calcula los valores de píxel:

 public static float calculateDpToPixel(float dp, Context context) { Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float px = dp * (metrics.densityDpi / 160f); return px; } 

Una función de memorización que devuelve el valor de HashMap y mantiene el registro de los valores anteriores.

La memorización se puede implementar de diferentes maneras en Java. Para Java 7 :

 public static float convertDpToPixel(float dp, final Context context) { Float f = pxCache.get(dp); if (f == null) { synchronized (pxCache) { f = calculateDpToPixel(dp, context); pxCache.put(dp, f); } } return f; } 

Java 8 admite la función Lambda :

 public static float convertDpToPixel(float dp, final Context context) { pxCache.computeIfAbsent(dp, y ->calculateDpToPixel(dp,context)); } 

Gracias.

A continuación, funtions funcionó bien para mí en todos los dispositivos.

Está tomado de https://gist.github.com/laaptu/7867851

 public static float convertPixelsToDp(float px){ DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); float dp = px / (metrics.densityDpi / 160f); return Math.round(dp); } public static float convertDpToPixel(float dp){ DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); float px = dp * (metrics.densityDpi / 160f); return Math.round(px); } 

// para obtener en términos de Decimal / Float

 public static float convertPixelsToDp(float px, Context context) { Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float dp = px / (metrics.densityDpi / 160f); return Math.round(dp); } public static float convertDpToPixel(float dp, Context context) { DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); float px = dp * (metrics.densityDpi / 160f); return Math.round(px); } // for getting in terms of Integer private int convertPxToDp(int px, Context context) { Resources resources = context.getResources(); return Math.round(px / (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT)); } private int convertDpToPx(int dp, Context context) { Resources resources = context.getResources(); return Math.round(dp * (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT)); } 

________________________________________________________________________________

 public static float convertPixelsToDp(float px){ DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); float dp = px / (metrics.densityDpi / 160f); return Math.round(dp); } public static float convertDpToPixel(float dp){ DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); float px = dp * (metrics.densityDpi / 160f); return Math.round(px); } private int convertDpToPx(int dp){ return Math.round(dp*(getResources().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT)); } private int convertPxToDp(int px){ return Math.round(px/(Resources.getSystem().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT)); } 

Si está buscando una calculadora en línea para convertir DP, SP, pulgadas, milímetros, puntos o píxeles entre sí a diferentes densidades de pantalla, esta es la herramienta más completa que conozco .

Puede usar [DisplayMatrics][1] y determinar la densidad de la pantalla. Algo como esto:

 int pixelsValue = 5; // margin in pixels float d = context.getResources().getDisplayMetrics().density; int margin = (int)(pixelsValue * d); 

Según recuerdo, es mejor usar pisos para compensaciones y redondeos para anchos.

Siéntase libre de usar este método que escribí:

 int dpToPx(int dp) { return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); } 

La respuesta aceptada anteriormente no es completamente precisa. De acuerdo con la información obtenida al inspeccionar el código fuente de Android:

Resources.getDimension() y getDimensionPixelOffset() / getDimensionPixelSize() difieren solo en que el primero devuelve float mientras que los dos últimos devuelven el mismo valor redondeado a int apropiatelly. Para todos ellos, el valor de retorno está en píxeles brutos.

Las tres funciones se implementan llamando a Resources.getValue() y convirtiendo TypedValue así obtenido llamando a TypedValue.complexToDimension() , TypedValue.complexToDimensionPixelOffset() y TypedValue.complexToDimensionPixelSize() , respectivamente.

Por lo tanto, si desea obtener un valor “en bruto” junto con la unidad especificada en la fuente XML, llame a Resources.getValue() y use los métodos de la clase TypedValue .

DisplayMetrics displayMetrics = contaxt.getResources () .getDisplayMetrics ();

  int densityDpi = (int) (displayMetrics.density * 160f); int ratio = (densityDpi / DisplayMetrics.DENSITY_DEFAULT); int px; if (ratio == 0) { px = dp; } else { px = Math.round(dp * ratio); } 

variación en la respuesta de ct_robs anterior, si está utilizando números enteros, que no solo evita dividir entre 0 sino que también produce un resultado utilizable en dispositivos pequeños:

en cálculos enteros que involucran división para mayor precisión, multiplique primero antes de dividir para reducir los efectos de truncamiento.

px = dp * dpi / 160 dp = px * 160 / dpi

5 * 120 = 600/160 = 3

en lugar de

5 * (120/160 = 0) = 0

si quieres un resultado redondeado haz esto

px = (10 * dp * dpi / 160 + 5) / 10 dp = (10 * px * 160 / dpi + 5) / 10

10 * 5 * 120 = 6000/160 = 37 + 5 = 42/10 = 4

con la ayuda de otras respuestas escribí esta función.

 public static int convertToPixels(Context context, int nDP) { final float conversionScale = context.getResources().getDisplayMetrics().density; return (int) ((nDP * conversionScale) + 0.5f) ; }