J'utilise des dessins vectoriels dans Android avant Lollipop et ceux-ci font partie de certaines de mes bibliothèques et versions d'outil:
J'ai ajouté cette propriété dans mon niveau d'application Build.Gradle
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Il est également intéressant de mentionner que j’utilise un dessin supplémentaire, tel que LayerDrawable (layer_list), comme indiqué dans le blog officiel Android ( lien ici ), pour le réglage des dessinables pour les vecteurs dessinables 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 un vecteur de référence se rapportant à l'extérieur de app: srcCompat échouera avant Lollipop. Cependant, AppCompat fait supporte le dessin des vecteurs dessinables quand ils sont référencés dans un autre conteneur dessinable tel que StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable et RotateDrawable. En utilisant ceci indirection, vous pouvez utiliser des dessins vectoriels dans des cas tels que TextView Android: attribut drawableLeft, qui ne serait normalement pas en mesure de support vectoriel tirables.
Lorsque j'utilise app:srcCompat
, tout fonctionne bien, mais lorsque j'utilise:
Android:background
Android:drawableLeft
Android:drawableRight
Android:drawableTop
Android:drawableBottom
sur ImageView
, ImageButton
, TextView
ou EditText
avant Lollipop, il déclenche une expection:
Caused by: Android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9
Je pense que cela se produit car Support Vector a été désactivé dans la dernière version de la bibliothèque: 23.3.0.
Selon ceci POST :
Pour les utilisateurs d’AppCompat, nous avons décidé de supprimer la fonctionnalité qui vous permet d’utiliser des éléments dessinables vectoriels à partir de ressources sur des appareils antérieurs à Lollipop en raison de problèmes rencontrés lors de l’implémentation de la version 23.2.0/23.2.1 (NUMÉRO 205236) . L'utilisation de app: srcCompat et setImageResource () continue de fonctionner.
Si vous visitez le numéro NUMÉRO 205236 , il semble que cela sera possible à l'avenir, mais le problème de mémoire ne sera pas résolu rapidement:
Dans la prochaine version, j'ai ajouté une API opt-in permettant de réactiver le support VectorDrawable supprimé. Il présente toutefois les mêmes réserves qu’avant (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 à nouveau toutes les icônes qui utilisent un vecteur tirable depuis une ressource vers des images PNG (car le problème de mémoire continuera de se produire même après qu’elles offrent une option pour le réactiver).
Je ne suis pas sûr que ce soit la meilleure option, mais à mon avis, cela corrige tous les crashs.
METTRE &AGRAVE; 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 afin de réactiver le support Vector Drawables à partir de ressources (comportement décrit dans 23.2) via AppCompatDelegate.setCompatVectorFromResourcesEnabled (true) - n'oubliez pas que cela Cela peut toujours entraîner des problèmes d’utilisation de la mémoire et des problèmes de mise à jour des instances de configuration, d’où sa désactivation par défaut.
Le paramètre Maybe, build.gradle
est maintenant obsolète et vous devez simplement l'activer dans les activités appropriées (cependant, vous devez effectuer un test).
Maintenant, pour l'activer, vous devez faire:
public class MainActivity extends AppCompatActivity {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
...
}
J'ai eu le même problème… .. Mais en faisant beaucoup de R & D, j'ai eu la réponse.
Pour utiliser Imageview et ImageButton, app: srcCompat = "@ drawable /...." Et pour d'autres vues comme Button, Textview, au lieu d'utiliser" drawableLeft/right ... "dans le code XML, spécifiez drawables par programme :
button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);
Et utilisez "AppCompatResources" pour obtenir le dessinable.
Pour élaborer l'autre très bonne réponse , voici un diagramme qui peut vous aider. Il est valide si vous avez Support Library de 23.4.0 à au moins 25.1.0.
La réponse de Guillherme P est assez impressionnante. 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);
}
N'OUBLIEZ PAS: 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 la bibliothèque de support supérieure à v23.4 lorsque Google a rajouté le support des conteneurs pouvant être dessinés pour VectorDrawables ( release note ).
Mettre à jour
Et pour les changements de code:
app:srcCompat
à chaque endroit qui accepte l'attribut Android:src
(le IDE vous avertira s'il est invalide, comme pour la balise <bitmap>
).Pour les attributs drawableLeft
, drawableStart
, drawableRight
, drawableEnd
utilisés dans TextView
et des vues similaires, vous devrez les définir par programme pour l'instant. Un exemple de paramètre drawableStart
:
Drawable drawable = AppCompatResources.getDrawable(
getContext(),
R.drawable.your_vector_drawable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
}
J'ai eu le même problème. Et le réparer en enlevant
vectorDrawables.useSupportLibrary = true
Ma version cible est 25 et la bibliothèque de support est
compile 'com.Android.support:appcompat-v7:25.3.1'
VectorDrawables sur pré-Lollipop devrait bien fonctionner sans utiliser
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
Si vous souhaitez utiliser VectorDrawables dans ImageViews, vous pouvez utiliser l'attribut srcCompat
et cela fonctionnera, mais à l'intérieur de Buttons ou de TextViews, il ne sera pas ; vous devez donc insérer le dessin dans un InsetDrawable ou un LayerDrawable. Il y a un autre truc que j'ai découvert, si vous utilisez la liaison de données, vous pouvez faire ceci:
Android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
Android:drawableStart="@{@drawable/vector_ic_access_time_24px}"
Comme par magie, je n’ai pas enquêté sur ce qui se passe dans les coulisses, mais je suppose que TextView utilise la méthode getDrawable de AppCompatResources ou similaire.
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
- Supprimez drawableleft , drawableright .... et définissez-le à partir de code Java modifiable.
txtview.setCompoundDrawablesWithIntrinsicBounds (AppCompatResources.getDrawable (EventDetailSinglePage.this, R.drawable.ic_done_black_24_n), null, null, null);
Pour Build.gradle
vectorDrawables.useSupportLibrary = true
Pour ceux qui passent à Android Gradle version 3.0 ou ultérieure, il n’est pas nécessaire d’utiliser AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
, ni de définir vectorDrawables.useSupportLibrary = true
(ajouter que cela pose problème) et d’utiliser app:srcCompat
, cela fonctionne.
Prenez-moi deux jours pour comprendre cela, et je n'ai pas trouvé de documents connexes dans les documents de Google ...
J'utilise VectorDrawables sur des périphériques Pre-Lollipop et voici comment je le fais: -
Étape 1: Mettez ceci dans votre classement de niveau d'application.
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Étape 2:
Mettez ceci dans votre classe Application et n'oubliez pas d'enregistrer votre classe Application dans le fichier manifeste.
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
Étape 3:
Obtenez VectorDrawables en utilisant,
imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
Après avoir utilisé le code ci-dessous.
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}}
encore, le problème des images vectorielles existe pour les attributs ci-dessous sont
DrawableEnd, DrawableStart, DrawableTop, DrawableBottom, Arrière-plan
Dans ce cas, veuillez suivre les instructions ci-dessous. Au lieu de référencer une image vectorielle, utilisez directement la balise selector en tant que fichier dessinable intermédiaire.
Exemple:
ic_warranty_icon.xml
<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:width="17dp"
Android:height="24dp"
Android:autoMirrored="true"
Android:viewportWidth="17"
Android:viewportHeight="24">
<path
Android:fillColor="#fff"
Android:pathData="M10.927,15.589l-1.549,0.355a7.47,7.47 0,0 1,-0.878 0.056c-4.136,0 -7.5,-3.364 -7.5,-7.5s3.364,-7.5 7.5,-7.5 7.5,3.364 7.5,7.5c0,3.286 -2.126,6.078 -5.073,7.089zM8.5,2a6.508,6.508 0,0 0,-6.5 6.5c0,3.583 2.917,6.5 6.5,6.5s6.5,-2.917 6.5,-6.5 -2.917,-6.5 -6.5,-6.5z" />
safe_ic_warranty_icon.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@drawable/ic_warranty_icon" />
</selector>
Votre TextView/Layout.
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:drawableStart="@drawable/ic_warranty_icon"
/>
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@drawable/ic_warranty_icon"
/>
Il suffit de superposer un vecteur pouvant être dessiné dans une liste d'états, puis le problème sera résolu
Par exemple, vous avez une image vectorielle de flèche de retour:
ic_back_arrow.xml
oui, vous devez le superposer à la liste des couches xml (ic_back_arrow_vector_vector.xml):
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@drawable/ic_back_arrow"/>
</layer-list>
Parce que la logique:
vectorDrawables.useSupportLibrary = true
et
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
ne vous aidera pas sur certains appareils en Chine et sur des appareils Samsung plus anciens. Si vous ne les superposez pas, cela échouera.
Nous avons essayé 3 choses
vectorDrawables.useSupportLibrary = true
Définition de setCompatVectorFromResourcesEnabled dans la classe d'application
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Et utilisez app:srcCompat
Mais même après ça échouait avec
Resources$NotFoundException: File res/drawable/$my_icon__0.xml from color state list resource ID #0x7f080008
ensuite, nous avons compris que notre SVG avait une balise Gradient. La conversion de la balise de dégradé en chemins individuels pour l'API ci-dessous <= 23 et l'utilisation de la même API SVG> = 24 ont fonctionné.
A obtenu de l'aide de cette réponse https://stackoverflow.com/a/47783962/217151
Moyen le plus simple d'utilisation:
app:drawableRightCompat ="@drawable/ic_mobilelogin"
app:drawableEndCompat="@drawable/ic_mobilelogin"
app:srcCompat="@drawable/ic_mobile"
et ... utilisez simplement l'application: ** Compat pour la compatibilité
Ajoutez également le support sur buil.gradle (Module)
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}