Utilisation de drawables vecteur Android sur crash pré Lollipop
J'utilise vector drawables dans android avant Lollipop et ce sont quelques-unes de mes bibliothèques et versions d'outils:
- Android Studio: 2.0
- Plugin Android Gradle: 2.0.0
- Outils De Construction: 23.0.2
- Bibliothèque De Support Android: 23.3.0
J'ai ajouté cette propriété dans mon niveau d'application Build.Gradle
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Il convient également de mentionner que j'utilise un drawable supplémentaire tel que LayerDrawable (layer_list) comme indiqué dans Android Blog officiel (lien ici ) pour définir les drawables pour les drawables vectoriels en dehors de app:srcCompat
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/search"/>
</level-list>
Vous trouverez directement des références vectorielles à l'extérieur de application: srcCompat échouera avant Lollipop. Cependant, AppCompat fait supporte le chargement des drawables vectoriels lorsqu'ils sont référencés dans un autre conteneur drawable tel Qu'un StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable et RotateDrawable. En utilisant ce indirection, vous pouvez utilisez des drawables vectoriels dans des cas tels que TextView Android: attribut drawableLeft, qui ne serait normalement pas capable de vecteurs de support un drawable.
Quand j'utilise app:srcCompat
Tout fonctionne bien, mais quand j'utilise:
android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom
Sur ImageView
, ImageButton
, TextView
ou EditText
avant la Sucette, elle lève une exception:
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
12 réponses
Je pense que cela se produit parce que le vecteur de Support a été désactivé dans la dernière version de la bibliothèque: 23.3.0
Selon ce POST - :
Pour les utilisateurs D'AppCompat, nous avons décidé de supprimer la fonctionnalité qui vous permet d'utiliser des drawables vectoriels à partir de ressources sur les périphériques pré-Lollipop en raison de problèmes trouvés dans l'implémentation dans la version 23.2.0/23.2.1 (numéro 205236). Utilisation de l'application: srcCompat et setImageResource () continue de fonctionner.
Si vous visitez problème problème 205236 , il semble qu'ils permettront à l'avenir mais le problème de mémoire ne sera pas résolu bientôt:
Dans la prochaine version, j'ai ajouté une API opt-in où vous pouvez réactiver le support VectorDrawable qui a été supprimé. Il est livré avec les mêmes mises en garde qu'auparavant (utilisation de la mémoire et problèmes de mise à jour de la Configuration).
J'ai eu un problème similaire. Donc, dans mon cas, j'ai rétabli toutes les icônes qui utilisent à nouveau le vecteur drawable de la ressource aux images PNG (puisque le problème de mémoire continuera à se produire même après qu'ils fournissent une option pour l'activer à nouveau).
Je ne suis pas sûr si c'est la meilleure option, mais cela corrige tous les accidents à mon avis.
Mise à JOUR
Ils ont réactivé ce VectorDrawable dans
bibliothèque de Support Android 23.4.0
Pour les utilisateurs D'AppCompat , nous avons ajouté une API opt-in pour réactiver les Drawables vectoriels de support à partir des ressources (le comportement trouvé dans 23.2) via AppCompatDelegate.setCompatVectorFromResourcesEnabled (true) - gardez à l'esprit que cela peut toujours causer des problèmes d'utilisation de la mémoire et des problèmes de mise à jour des instances de Configuration, d'où la désactivation par défaut.
Peut être, build.gradle
le paramètre est maintenant obsolète et vous avez juste besoin de l'activer dans les activités appropriées (cependant, besoin de tester).
Maintenant, pour l'activer, vous devez faire:
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
...
}
Pour élaborer sur l'autre de très bonnes réponses , Voici un diagramme qui peut vous aider. Il est valide si vous avez une bibliothèque de Support de 23.4.0 à au moins 25.1.0.
J'ai eu le même problème. Mais faire beaucoup de R & D j'ai eu la réponse.
Pour Imageview et ImageButton utiliser, app: srcCompat= " @drawable/...." et pour d'autres vues comme Button, Textview, au lieu d'utiliser "drawableLeft/right..."dans le XML, spécifiez les drawables par programmation comme suit:
button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);
Et utilisez "AppCompatResources" pour obtenir le drawable.
La réponse de Guillherme P est assez géniale. Juste pour faire une petite amélioration, vous n'avez pas besoin d'ajouter cette ligne dans chaque activité, si vous l'avez ajoutée une fois dans la classe Application, cela fonctionnera également.
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Rappelez-vous: vous devez toujours avoir activé l'utilisation de la bibliothèque de support dans gradle:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Assurez-vous également que vous utilisez une version de bibliothèque de support supérieure à v23.4, Lorsque Google a ajouté la prise en charge des conteneurs Drawable pour VectorDrawables (note de version )
NOTE : quoi qu'il en soit, je suggère d'utiliser les fichiers PNG jusqu'à ce que Google trouve une meilleure solution ou que vous ayez des problèmes de mémoire.
VectorDrawables sur pré-lollipop devrait fonctionner correctement sans utiliser
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Si vous voulez utiliser VectorDrawables dans ImageViews, vous pouvez utiliser L'attribut srcCompat
et cela fonctionnera, mais à L'intérieur des boutons ou des TextViews IL ne sera pas , vous devez donc envelopper le Drawable dans un InsetDrawable ou un LayerDrawable. Il y a une autre astuce que j'ai découverte, si vous utilisez la liaison de données, vous pouvez le faire:
android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
Cela fonctionnera comme par magie, je n'ai pas enquêté sur ce qui se passe derrière les scènes, mais je suppose que le TextView utilise la méthode getDrawable de L'AppCompatResources ou similaire.
J'ai eu le même problème. Et corrigez-le en supprimant
vectorDrawables.useSupportLibrary = true
MA version cible est 25 et la bibliothèque de support est
compile 'com.android.support:appcompat-v7:25.3.1'
Pour tous ceux qui mettent à niveau vers Android gradle 3.0 et supérieur, il n'est pas nécessaire d'utiliser AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
, ou de définir vectorDrawables.useSupportLibrary = true
(Ajouter cela causera un problème) et d'utiliser app:srcCompat
, cela fonctionne.
Prenez-moi deux jours pour comprendre cela, et n'ont pas trouvé de documents connexes dans les documents de google...
J'utilise VectorDrawables sur les appareils pré-lollipop et voici comment je le fais: -
Étape 1: Mettez ceci dans votre gradle de niveau d'application.
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Étape 2:
Mettez ceci dans votre classe D'Application et n'oubliez pas d'enregistrer votre classe D'Application dans le fichier manifeste.
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
Étape 3:
Obtenir VectorDrawables en utilisant,
imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
Beaucoup de R & d, enfin obtenir cette solution pour les accidents sur les appareils pré-lollipop.
Pour Imageview
- utiliser app:srcCompat, au lieu d'android:src
Pour TextView / EditText
- Supprime drawableleft,drawableright.... et défini à partir du code java drawable.
Txtview.setCompoundDrawablesWithIntrinsicbounds (AppCompatResources.getDrawable (EventDetailSinglePage.ce, R. drawable.ic_done_black_24_n), null, null, null);
Pour Construire.gradle
VectorDrawables.useSupportLibrary = true
La suggestion de Guilherme P ne fonctionnait pas pour moi. Je suis allé de l'avant et j'ai pris la décision d'utiliser png où je dois faire des choses en dehors de l'application:srcCompat c'est-à-dire drawableLeft, drawableRight, etc. C'était un changement assez facile à faire, et n'a pas les problèmes de mémoire potentiels AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); introduit.
Il existe une solution plus simple maintenant, il suffit d'utiliser app: drawableRightCompat à partir de l'espace de noms de l'application.
Ou dans le style:
<style name="YourStyle">
<item name="drawableRightCompat">@drawable/your_vector</item>
</style>
Une alternative à la réponsede de Benny est de créer une superclasse Activity
:
public abstract class VectorDrawableActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
//...
}
Maintenant étendre VectorDrawableActivity
au lieu de AppCompatActivity
.