¿Cuál es la diferencia entre -anydpi y -nodpi?

108

Si usa el asistente de activos vectoriales en Android Studio 1.5.0, cualquier XML de diseño vectorial que importe con ese asistente entrará en res/drawable/.

Sin embargo, el build/directorio y el APK resultante muestran que esos archivos XML se mueven a un res/drawable-anydpi-v21/directorio de recursos. La -v21parte tiene sentido, ya VectorDrawableque solo es compatible con API Level 21+. Sin embargo, -anydpiparece estar indocumentado. Hubiera esperado -nodpi, tanto para el destino de importación original como para el lugar donde el sistema de compilación elige moverlo.

¿Alguien ha visto declaraciones oficiales para qué -anydpimedios y con qué relación está -nodpi? Estoy buscando efectos prácticos, no simplemente lo que sugieren algunos comentarios de código.

CommonsWare
fuente

Respuestas:

106

nodpi

Estos son recursos independientes de la densidad. El sistema no escala los recursos etiquetados con este calificador, independientemente de la densidad de la pantalla actual.

Por ejemplo:

  • drawable- nodpi /dot.png

El punto aparecerá pequeño en xxhdpi, grande en ldpi.

Sin embargo, el solucionador de recursos coincidirá con un calificador específico si existe.

Por ejemplo

  • drawable- IPAP /eg.png
  • drawable- nodpi -v21 / eg.xml

En un dispositivo hdpi Lollipop (API 21), se utiliza el mapa de bits .

En un dispositivo xhdpi Lollipop (API 21), se utiliza el vector.

anydpi

Estos recursos tienen prioridad en cualquier ppp.

Por ejemplo

  • drawable- IPAP /eg.png
  • drawable- anydpi -v21 / eg.xml

En un dispositivo hdpi Lollipop (API 21), se utiliza el vector .

En un dispositivo xhdpi Lollipop (API 21), se utiliza el vector.

Referencia

Nota : anydpi se agregó en el cambio Ic3288d0236fe0bff20bb1599aba2582c25b0db32 .

rds
fuente
Eso no es lo que estoy viendo. Citando mi recompensa: "Dadas dos ediciones del mismo recurso en res / drawable-nodpi / y res-drawable-mdpi /, obtengo la edición res / drawable-nodpi / en un Nexus 5 con Android 6.0, que es un -xxhdpi dispositivo". ¿Tiene un proyecto de muestra que demuestre el comportamiento que está citando?
CommonsWare
Eso es porque usaste drawable. El comportamiento del SDK puede haber cambiado. Ver VectorDrawable: Android carga PNG xhdpi en lugar del recurso vectorial
rds
"Eso es porque usaste dibujable", también lo hiciste en tu respuesta. Cada directorio de recursos que cita en su respuesta es un drawabledirectorio de recursos, al igual que los dos directorios que cité en mi recompensa son drawabledirectorios de recursos.
CommonsWare
"En un xxxdpi, el marco tomará el mapa de bits hdpi". - eso es específicamente lo que no está sucediendo, aunque mi prueba está en un -xxhdpidispositivo. Tengo res/drawable-mdpi/nodpi_and_m.pngy res/drawable-nodpi/nodpi_and_m.xml. En un -xxhdpidispositivo Nexus 5, el recurso que se utiliza es res/drawable-nodpi/nodpi_and_m.xml. De acuerdo con su algoritmo, y mis expectativas, res/drawable-mdpi/nodpi_and_m.pngdebería usarse. Eso no es lo que está pasando.
CommonsWare
2
En pocas palabras: debes colocar vectores en formato drawable-anydpi-v21. Si tiene la biblioteca de dibujo vectorial de soporte, puede colocarlos en drawable-anydpio simplemente drawable.
rds
17

El código fuente contiene los siguientes comentarios (línea 639):

/**
 * Value for {@link #densityDpi} for resources that scale to any density (vector drawables).
 * {@hide}
 */
public static final int DENSITY_DPI_ANY = 0xfffe;

/**
 * Value for {@link #densityDpi} for resources that are not meant to be scaled.
 * {@hide}
 */
public static final int DENSITY_DPI_NONE = 0xffff;

Espero que esto aclare la confusión.

Vishavjeet Singh
fuente
8
"Espero que esto aclare la confusión", en realidad no. No está claro cuál es la diferencia entre "escalar a cualquier densidad" y "no destinado a ser escalado" significan en la práctica. Los elementos de diseño en los -nodpidirectorios se escalan con toda seguridad en función del tamaño, de acuerdo con las reglas que existan sobre cómo se utiliza el elemento de diseño.
CommonsWare
"No destinado a escalar" significa que no se escalarán sin importar lo que haga el programador o la densidad.
Vishavjeet Singh
Creo que quieren decir con la frase "escalar a cualquier densidad" que se refieren a elementos de dibujo vectoriales que se escalarán para adaptarse a cualquier densidad sin importar cuán grande sea la densidad.
Vishavjeet Singh
3
¡Se agregó en android.googlesource.com/platform/frameworks/base/+/31245b4%5E! , y de él puede aprender que probablemente haya solucionado algún error 17007265
marcinj
1
@ MarcinJędrzejewski: En realidad, "se eligen como la mejor coincidencia a menos que haya una configuración que coincida exactamente con la densidad solicitada". El comentario sobre esa confirmación me da una pista. ¡Gracias!
CommonsWare
10

nodpi: Recursos para todas las densidades. Estos son recursos independientes de la densidad. El sistema no escala los recursos etiquetados con este calificador, independientemente de la densidad de la pantalla actual.

anydpi: Este calificador coincide con todas las densidades de pantalla y tiene prioridad sobre otros calificadores. Esto es útil para elementos de diseño vectoriales. Agregado en API Nivel 21.

dzikovskyy
fuente
9

Utilizo drawable-nodpi para todo, incluidos muchos gráficos grandes para mi juego. Una consecuencia indocumentada de escalar sus gráficos es que aumenta exponencialmente el uso de memoria. Por lo tanto, si tiene un gráfico de 1 MB que se puede dibujar, se escalará a 4 MB, 16 MB o 64 MB según la resolución del dispositivo del usuario. Y las resoluciones de los dispositivos siguen aumentando. Esa ampliación en realidad no aumenta la nitidez del gráfico, por supuesto. Las acciones de dibujo pueden determinar el tamaño de cada gráfico en relación con el tamaño de la pantalla de todos modos, sin necesidad de llenar la aplicación con varias carpetas de dibujo.

Androidcoder
fuente
3
respuesta subestimada. Encontré el mismo problema: tenía una imagen de 100 KB de tamaño, pero con frecuencia tenía errores OOM al cargarla. ¡La aplicación se bloqueó indicando que no podía asignar 18 MB! No pude entender cómo estos 100 KB podrían convertirse en 18 MB, pero en realidad fue el resultado de esa escala. Cambiar la imagen a no-dpi resolvió el problema.
Simon Ninon