Android y configuración de ancho y alto mediante programación en unidades dp


304

Estoy haciendo:

button.setLayoutParams(new GridView.LayoutParams(65, 65));

De acuerdo con los documentos, las unidades para el ancho y la altura (ambas 65 en el anterior) son "píxeles". ¿Cómo obliga a que se trate de píxeles independientes del dispositivo o "dp"?

Respuestas:


541

Tendrá que convertirlo de dps a píxeles utilizando el factor de escala de visualización.

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);

111
La conversión correcta es (int) (dps * scale + 0.5f). Esta es la fórmula que usamos en todo el marco.
Romain Guy

8
La fórmula está en los documentos. Para leer más, vaya a la sección 3 de developer.android.com/guide/practices/…
SK9

34
@RomainGuy, ¿puede agregar una función de utilidad a la API para convertir de dpa px? Gracias.
AlikElzin-kilaka

3
¿Qué es dps aquí? estoy obteniendo el error "dps no se puede resolver a una variable"? ¿Qué tipo de "dps" necesita declarar?
Deepak

55
La variable "dps" es el valor de entrada que desea convertir.
Robby Pond

233

Sé que esta es una vieja pregunta, sin embargo, he encontrado una forma mucho más ordenada de hacer esta conversión.

Java

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());

Kotlin

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)

8
Bien hecho por descubrir cómo hacer esto. ¡No soy fanático de repetir una fórmula en varios lugares! Gracias.
darrenp

2
Si no, cree una función con la fórmula
Sayka

1
@Kenobi Realiza la conversión por usted de DP a PX. Lo 65anterior es el valor DP que desea convertir a PX
drspaceboo

77
Esta debería ser la respuesta aceptada, no la actual donde estos números (0.5) provienen mágicamente de ninguna parte
Johny19

1
@ Johny19 El 0.5 no es mágico. Es solo cómo redondear un número de coma flotante al entero más cercano en lugar de truncarlo. Vea mi comentario sobre la respuesta de Robby Pond para más detalles.
MarredCheese

38

Mirando su requerimiento, también hay una solución alternativa. Parece que conoce las dimensiones en dp en tiempo de compilación, por lo que puede agregar una entrada de dimen en los recursos. Luego puede consultar la entrada de dimen y se convertirá automáticamente a píxeles en esta llamada:

final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);

Y tu dimens.xml tendrá:

<dimen name="dimen_entry_in_dp">72dp</dimen>

Extendiendo esta idea, simplemente puede almacenar el valor de 1dp o 1sp como una entrada de dimen y consultar el valor y usarlo como un multiplicador. Con este enfoque, aislará el código del material matemático y dependerá de la biblioteca para realizar los cálculos.


Tenga en cuenta que el valor de retorno es en realidad un int, por lo que se convierte en flotante.
CorayThan

Esta es una mala respuesta porque es muy dinámico
Johny19

37

La forma más simple (e incluso funciona desde la API 1) que probó es:

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

De documentaciones:

Recupere una dimensión para un ID de recurso particular para usar como tamaño en píxeles sin formato. Esto es lo mismo que getDimension (int), excepto que el valor devuelto se convierte a píxeles enteros para su uso como tamaño. Una conversión de tamaño implica redondear el valor base y garantizar que un valor base distinto de cero tenga al menos un píxel de tamaño.

Sí, redondeando el valor, pero no es muy malo (solo en valores impares en dispositivos hdpi y ldpi necesitan agregar un pequeño valor cuando ldpi no es muy común) Lo probé en un dispositivo xxhdpi que convierte 4dp a 16 (píxeles) y eso es cierto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.