Estoy tratando de calcular una cantidad variable de píxeles en píxeles independientes de la densidad y viceversa.
Esta fórmula (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160));
no funciona en dispositivos pequeños porque está dividida por cero.
Esta es mi fórmula de dp a px:
px = (int)(dp * (displayMetrics.densityDpi / 160));
¿Alguien podría darme algunos consejos?
Respuestas:
Nota: La solución ampliamente utilizada anterior se basa en
displayMetrics.density
. Sin embargo, los documentos explican que este valor es un valor redondeado, utilizado con los 'cubos' de la pantalla. 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 ser mezclado con la unidad dp interna de Android, ya que esto, por supuesto, todavía se basa en los cubos de la pantalla. Use esto donde desee una unidad que debería representar el mismo tamaño real en diferentes dispositivos.
Convierta dp a píxel:
Convierte píxeles a dp:
Tenga en cuenta que hay propiedades xdpi e ydpi, es posible que desee distinguir, pero no puedo imaginar una visualización sensata en la que estos valores difieran mucho.
fuente
Resolví mi problema usando las siguientes fórmulas. Que otras personas se beneficien de ello.
dp a px:
px a dp:
fuente
px a dp:
fuente
typedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, valueInDp , getResources() .getDisplayMetrics());
es de PX a DP, también esta es la mejor respuestaapplyDimension
solo produce píxeles. Consulte android.googlesource.com/platform/frameworks/base/+/refs/heads/… en el que no se realiza ninguna conversiónCOMPLEX_UNIT_PX
.dp
. Si observa el código fuente, para el casoTypedValue.COMPLEX_UNIT_DIP
,value * metrics.density
se devuelve, donde realmente lo necesitavalue * metrics.density
. Entonces, lo que está obteniendo` valueInDp` NO estádp
paravalueInPx
adentropx
.value / metrics.density
"De manera eficiente siempre
DP a píxel:
Pixel a DP:
Espero que esto te ayudará.
fuente
displayMetrics.xdpi
que es diferente en cualquier dispositivo. Lamentablemente, esta respuesta incorrecta también tiene más votos a favor.private fun dpToPx(dp: Int) = (dp * Resources.getSystem().displayMetrics.density).toInt()
Simplemente llame
getResources().getDimensionPixelSize(R.dimen.your_dimension)
para convertir dedp
unidades a píxelesfuente
Use esta función
fuente
fuente
(displayMetrics.densityDpi / 160)
- esta parte puede obtener 0 en dispositivos pequeños, allí calcula, por ejemplo120/160
, ambos valores son int, lo que resulta en 0. Lo que termina como(int) (px/0)
.En la mayoría de los casos, las funciones de conversión se llaman con frecuencia. Podemos optimizarlo agregando memorización. Por lo tanto, no calcula cada vez que se llama a la función.
Declaremos un HashMap que almacenará los valores calculados.
Una función que calcula valores de píxeles:
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 :
Java 8 admite la función Lambda :
Gracias.
fuente
prueba esto http://labs.skinkers.com/content/android_dp_px_calculator/
fuente
Las siguientes funciones funcionaron bien para mí en todos los dispositivos.
Está tomado de https://gist.github.com/laaptu/7867851
fuente
Puede usar
[DisplayMatrics][1]
y determinar la densidad de la pantalla. Algo como esto:Como recuerdo, es mejor usar pisos para desplazamientos y redondeos para anchos.
fuente
Si está buscando una calculadora en línea para convertir DP, SP, pulgadas, milímetros, puntos o píxeles entre sí con diferentes densidades de pantalla, esta es la herramienta más completa que conozco .
fuente
// para obtener en términos de decimal / flotante
________________________________________________________________________________
fuente
Use estas extensiones de Kotlin:
fuente
Siéntase libre de usar este método que escribí:
fuente
La respuesta aceptada anteriormente no es totalmente precisa. Según la información obtenida al inspeccionar el código fuente de Android:
Resources.getDimension()
ygetDimensionPixelOffset()
/getDimensionPixelSize()
difiero solo en que el primero devuelvefloat
mientras que los dos últimos devuelven el mismo valor redondeado aint
apropiadamente. Para todos ellos, el valor de retorno está en píxeles sin formato.Las tres funciones son implementedy llamando
Resources.getValue()
y convertir así obtenidaTypedValue
llamandoTypedValue.complexToDimension()
,TypedValue.complexToDimensionPixelOffset()
yTypedValue.complexToDimensionPixelSize()
, respectivamente.Por lo tanto, si desea obtener un valor "en bruto" junto con la unidad especificada en la fuente XML, llame
Resources.getValue()
y use los métodos de laTypedValue
clase.fuente
Con la ayuda de otras respuestas escribí esta función.
fuente
Aquí hay otra forma de hacerlo usando las extensiones de kotlin:
y luego se puede usar así desde cualquier lugar
fuente
fuente
La variación de la respuesta ct_robs anterior, si está utilizando números enteros, que no solo evita dividir por 0, 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.
en vez de
si quieres un resultado redondeado haz esto
fuente