Quelle est la différence entre -anydpi et -nodpi?

108

Si vous utilisez l'assistant Vector Asset dans Android Studio 1.5.0, tout fichier XML dessinable vectoriel que vous importez à l'aide de cet assistant entre dans res/drawable/.

Cependant, le build/répertoire et l'APK résultant montrent que ces fichiers XML sont déplacés dans un res/drawable-anydpi-v21/répertoire de ressources. La -v21partie a du sens, car elle VectorDrawablen'est prise en charge que sur l'API Level 21+. Cependant, -anydpisemble être non documenté. Je me serais attendu -nodpi, à la fois pour la destination d'importation d'origine et pour l'endroit où le système de construction choisit de le déplacer.

Quelqu'un a-t-il vu des déclarations officielles sur quels -anydpimoyens et avec quoi sa relation est-elle -nodpi? Je recherche des effets pratiques, pas seulement ce que suggèrent certains commentaires de code.

CommonsWare
la source

Réponses:

106

hochement de tête

Ce sont des ressources indépendantes de la densité. Le système ne met pas à l'échelle les ressources étiquetées avec ce qualificatif, quelle que soit la densité de l'écran actuel.

Par exemple:

  • dessinable- nodpi /dot.png

Le point apparaîtra petit sur xxhdpi, grand sur ldpi.

Cependant, le résolveur de ressources correspondra à un qualificatif spécifique s'il existe.

Par exemple

  • dessinable- hdpi /eg.png
  • dessinable- nodpi -v21 / eg.xml

Sur un périphérique hdpi Lollipop (API 21), le bitmap est utilisé.

Sur un périphérique xhdpi Lollipop (API 21), le vecteur est utilisé.

anydpi

Ces ressources ont la priorité dans tous les dpi.

Par exemple

  • dessinable- hdpi /eg.png
  • dessinable- anydpi -v21 / eg.xml

Sur un périphérique hdpi Lollipop (API 21), le vecteur est utilisé.

Sur un périphérique xhdpi Lollipop (API 21), le vecteur est utilisé.

Référence

Remarque : anydpi a été ajouté dans le changement Ic3288d0236fe0bff20bb1599aba2582c25b0db32 .

rds
la source
Ce n'est pas ce que je vois. Citant ma prime: "Étant donné deux éditions de la même ressource dans res / drawable-nodpi / et res-drawable-mdpi /, j'obtiens le res / drawable-nodpi / edition sur un Nexus 5 exécutant Android 6.0, qui est un -xxhdpi dispositif". Avez-vous un exemple de projet qui démontre le comportement que vous citez?
CommonsWare
C'est parce que vous avez utilisé drawable. Le comportement du SDK peut avoir changé. Voir VectorDrawable: Android charge des fichiers PNG xhdpi au lieu de la ressource vectorielle
rds
"C'est parce que vous avez utilisé drawable" - vous aussi dans votre réponse. Chaque répertoire de ressources que vous citez dans votre réponse est un drawablerépertoire de ressources, tout comme les deux répertoires que j'ai cités dans ma prime sont drawabledes répertoires de ressources.
CommonsWare
"Sur un xxxdpi, le framework prendra le bitmap hdpi." - c'est précisément ce qui ne se passe pas, bien que mes tests soient sur un -xxhdpiappareil. J'ai res/drawable-mdpi/nodpi_and_m.pnget res/drawable-nodpi/nodpi_and_m.xml. Sur un appareil Nexus 5, -xxhdpila ressource utilisée est res/drawable-nodpi/nodpi_and_m.xml. Selon votre algorithme, et mes attentes, res/drawable-mdpi/nodpi_and_m.pngdoit être utilisé. Ce n'est pas ce qui se passe.
CommonsWare
2
En bout de ligne: vous devez placer des vecteurs drawable-anydpi-v21. Si vous disposez de la bibliothèque support-vector-drawable, vous pouvez les placer dans drawable-anydpiou simplement drawable.
rds
17

Le code source contient les commentaires suivants (ligne 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;

J'espère que cela dissipe la confusion.

Vishavjeet Singh
la source
8
"J'espère que cela dissipe la confusion" - pas vraiment. On ne sait pas quelle est la différence entre «échelle à toute densité» et «non destiné à être mis à l'échelle» dans la pratique. Les dessinables dans les -nodpirépertoires sont très certainement mis à l'échelle en fonction de leur taille, selon les règles en place pour l'utilisation du dessinable.
CommonsWare
«Non destinés à être mis à l'échelle» signifie qu'ils ne seront pas mis à l'échelle, peu importe ce que fait le programmeur ou la densité.
Vishavjeet Singh
Je pense qu'ils veulent dire par l'expression "échelle à n'importe quelle densité" qu'ils se réfèrent à des éléments vectoriels qui seront mis à l' échelle pour s'adapter à n'importe quelle densité, quelle que soit la densité.
Vishavjeet Singh
3
il a été ajouté dans android.googlesource.com/platform/frameworks/base/+/31245b4%5E! , et à partir de là, vous pouvez apprendre qu'il a probablement corrigé un bogue 17007265
marcinj
1
@ MarcinJędrzejewski: En fait, le commentaire "sont choisis comme meilleur match à moins qu'il n'y ait une configuration qui correspond exactement à la densité demandée" le commentaire sur ce commit me donne un indice. Merci!
CommonsWare
10

nodpi: Ressources pour toutes les densités. Ce sont des ressources indépendantes de la densité. Le système ne met pas à l'échelle les ressources étiquetées avec ce qualificatif, quelle que soit la densité de l'écran actuel.

anydpi: Ce qualificatif correspond à toutes les densités d'écran et a la priorité sur les autres qualificatifs. Ceci est utile pour les dessins vectoriels. Ajouté au niveau d'API 21.

dzikovskyy
la source
9

J'utilise drawable-nodpi pour tout, y compris beaucoup de grands graphiques pour mon jeu. Une conséquence non documentée de la mise à l'échelle de vos graphiques est qu'elle augmente l'utilisation de la mémoire de manière exponentielle. Donc, si vous avez un graphique de 1 Mo en dessin, il sera mis à l'échelle à 4 Mo, 16 Mo ou 64 Mo en fonction de la résolution de la machine utilisateur. Et les résolutions des appareils ne cessent d'augmenter. Cette mise à l'échelle n'augmente pas réellement la netteté du graphique, bien sûr. Les actions de dessin peuvent de toute façon déterminer la taille de chaque graphique par rapport à la taille de l'écran, pas besoin de gonfler l'application avec plusieurs dossiers de dessin.

Androidcoder
la source
3
réponse sous-estimée. J'ai rencontré le même problème: j'avais une image de 100 Ko, mais j'avais souvent des erreurs de MOO lors de son chargement. L'application s'est plantée, indiquant qu'elle ne pouvait pas allouer 18 Mo !!! Je ne pouvais pas comprendre comment ces 100 Ko pouvaient être transformés en 18 Mo, mais c'était en fait le résultat de cette mise à l'échelle. Le passage de l'image à no-dpi a résolu le problème.
Simon Ninon