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"?

SK9
fuente

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);
Estanque Robby
fuente
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)
drspaceboo
fuente
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.

viña
fuente
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.

David
fuente