Android getResources (). GetDrawable () API obsolète 22

699

Avec la nouvelle API Android 22 getResources().getDrawable()est désormais obsolète. Maintenant, la meilleure approche consiste à utiliser uniquement getDrawable().

Qu'est ce qui a changé?

Blodhgard
la source
Pourriez-vous préciser votre question? Il est juste que la méthode getDrawable (int id)de la classe Resourcessoit déconseillée. Vous devez maintenant utiliser la méthode getDrawable (int id, Resources.Theme theme)avec le nouveau paramètre de thème.
code singe
1
ContextCompat.getDrawable (context, R.color.color_name)
Ashokchakravarthi Nagarajan
Vous pouvez consulter mon article de blog sur ce sujet pour une explication plus approfondie des raisons pour lesquelles les deux Resources#getDrawable(int)et Resources#getColor(int)ont été dépréciés.
Alex Lockwood
1
Google devrait mettre des correctifs rapides pour chaque fonction obsolète. J'ai fait un post à ce sujet ici: code.google.com/p/android/issues/detail?id=219495
développeur Android

Réponses:

1027

Vous avez quelques options pour gérer cette dépréciation de la bonne manière (et à l' épreuve du temps ), selon le type de dessin que vous chargez:


A) Drawables avec des attributs de thème

ContextCompat.getDrawable(getActivity(), R.drawable.name);

Vous obtiendrez un dessinable de style selon les instructions de votre thème d'activité. C'est probablement ce dont vous avez besoin.


B) Drawables sans attributs de thème

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

Vous obtiendrez votre dessinable sans style à l'ancienne. Attention: ResourcesCompat.getDrawable()n'est pas déprécié!


EXTRA) drawables avec des attributs de thème d' un autre thème

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);
araks
la source
Mon application se bloque en utilisant la suggestion B. Elle n'aime pas l'appel Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null);
FractalBob
Je le déclare de cette façon: public static void setImageButtonEnabled (Context ctxt, boolean enabled, ImageButton item, int iconResId) {item.setEnabled (enabled); DrawI originalIcon = ResourcesCompat.getDrawable (ctxt.getResources (), iconResId, null); Icône dessinable = activée? originalIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (icône); } et appelez-le comme ceci: Utility.setImageButtonEnabled (getContext (), false, back, R.drawable.arrow_left);
FractalBob
Plus précisément, le crash semble se produire car mon icône est un vecteur dessinable.
FractalBob
1
version de xamarin: ResourcesCompat.GetDrawable (Resources, Resource.Drawable.name, null);
Brian
Je vous ajoute encore un mot you ContextCompat.getColor (contexte, couleur) peut également vous aider ...
BertKing
746

Edit: voir mon blog sur le sujet pour une explication plus complète


Vous devez plutôt utiliser le code suivant de la bibliothèque de support:

ContextCompat.getDrawable(context, R.drawable.***)

L'utilisation de cette méthode équivaut à appeler:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

À partir de l'API 21, vous devez utiliser la getDrawable(int, Theme)méthode au lieu de getDrawable(int), car elle vous permet de récupérer un objet dessinable associé à un ID de ressource particulier pour la densité / le thème d'écran donné. Appeler la getDrawable(int)méthode obsolète équivaut à appeler getDrawable(int, null).

Alex Lockwood
la source
8
Je pense que l'OP fait également référence à la getDrawable (int id)méthode de la Contextclasse. C'est la même chose getResources().getDrawable(id, getTheme());et utilise également la nouvelle API.
singe code
9
Selon la documentation, le niveau minimum d'API 21 est requis pour utiliser getDrawable(int, Resources.Theme).
Prince
@Prince La méthode a été ajoutée dans l'API 21 mais elle n'a pas été déconseillée avant l'API 22. :)
Alex Lockwood
La documentation Android recommande également d'utiliser la méthode Context :: getDrawable (int), mais comme elle n'a été introduite que dans l'API 21, ContextCompat semble être le meilleur choix.
goRGon
Cette réponse ne fonctionne pas avec les fichiers .svg, dans les versions antérieures à l'API 21. Il y a un bogue dans la bibliothèque.
Jorge Rodríguez
141

Remplacez cette ligne: getResources().getDrawable(R.drawable.your_drawable)

avec ResourcesCompat.getDrawable(getResources(), R.drawable.your_drawable, null)

ÉDITER

ResourcesCompatest également obsolète maintenant. Mais vous pouvez utiliser ceci:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(Voici thisle contexte)

pour plus de détails suivez ce lien: ContextCompat

vincent091
la source
2
C'est désormais privé: plus.google.com/+BenjaminWeiss/posts/M1dYFaobyBM
Xyaren
voir ce lien s'il vous plaît: developer.android.com/reference/android/support/v4/content/… , int)
vincent091
2
Il ne dit pas dans le lien qui ResourcesCompatest obsolète. Cela devrait bien fonctionner.
Jacob R
quoi écrire dans "votre dessinable" si je veux entrer des images dans une vue de liste en cliquant sur les éléments de la liste stockés dans le dessinable
0x0001
29

getResources().getDrawable() était obsolète dans l'API niveau 22. Maintenant, nous devons ajouter le thème:

getDrawable (int id, Resources.Theme theme) (Ajouté dans l'API niveau 21)

Ceci est un exemple:

myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));

Voici un exemple de validation pour les versions ultérieures:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));
   } else { 
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage));
}
Jorgesys
la source
Build.VERSION_CODES.LOLLIPOP is API 21, Ne devrait donc pas être if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)ou if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Ça ne fait rien. Par le bas "La méthode a été ajoutée dans l'API 21 mais elle n'a été déconseillée qu'à partir de l'API 22. :)"
Mark Cramer
2

Vous pouvez utiliser

ContextCompat.getDrawable(getApplicationContext(),R.drawable.example);

c'est du travail pour moi

Dasser Basyouni
la source
Utilisation du contexte d'application pour charger les plantages vectoriels dessinables sur la pré-sucette. Une solution pour ça?
muthuraj
1
@muthuraj Je ne me souviens pas de mes tests pour le code avec la sucette, mais vous pouvez essayer getActivity () ou getResources () à la place, est-ce que cela va bien avec votre code?
Dasser Basyouni
J'utilise le modèle MVVM et j'ai besoin de gonfler les dessinables à l'intérieur de ViewModels qui n'ont pas de contexte d'activité. Il n'a qu'un contexte d'application. Voilà mon problème.
muthuraj
1

Juste un exemple de la façon dont j'ai résolu le problème dans un tableau pour charger une listView, j'espère que cela aide.

 mItems = new ArrayList<ListViewItem>();
//    Resources resources = getResources();

//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.az_lgo), getString(R.string.st_az), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.ca_lgo), getString(R.string.st_ca), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.co_lgo), getString(R.string.st_co), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.az_lgo, null), getString(R.string.st_az), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.ca_lgo, null), getString(R.string.st_ca), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.co_lgo, null), getString(R.string.st_co), getString(R.string.all_nums)));
Geai
la source
1

Essaye ça:

public static List<ProductActivity> getCatalog(Resources res){
    if(catalog == null) {
        catalog.add(new Product("Dead or Alive", res
                .getDrawable(R.drawable.product_salmon),
                "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
        catalog.add(new Product("Switch", res
                .getDrawable(R.drawable.switchbook),
                "Switch by Chip Heath and Dan Heath", 24.99));
        catalog.add(new Product("Watchmen", res
                .getDrawable(R.drawable.watchmen),
                "Watchmen by Alan Moore and Dave Gibbons", 14.99));
    }
}
syakirin mohd ni
la source
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
Donald Duck
1

Si vous ciblez SDK> 21 (lollipop ou 5.0), utilisez

context.getDrawable(R.drawable.your_drawable_name)

Voir les documents

Adeel Ahmad
la source
1

getDrawable (int drawable) est obsolète dans l'API niveau 22. Pour référence, voir ce lien .

Maintenant, pour résoudre ce problème, nous devons passer un nouveau constructeur avec id comme: -

getDrawable(int id, Resources.Theme theme)

Pour les solutions Faites comme ceci: -

En Java: -

ContextCompat.getDrawable(getActivity(), R.drawable.name);   

ou

 imgProfile.setImageDrawable(getResources().getDrawable(R.drawable.img_prof, getApplicationContext().getTheme()));

À Kotlin: -

rel_week.background=ContextCompat.getDrawable(this.requireContext(), R.color.colorWhite)

ou

 rel_day.background=resources.getDrawable(R.drawable.ic_home, context?.theme)

J'espère que cela vous aidera. Merci.

Rahul Kushwaha
la source
Il convient de mentionner que getDrawable (id int DrawableRes, thème Theme) peut lever une exception si la ressource n'est pas trouvée tandis que getDrawable (contexte contextuel, id int) est nullable, donc doit-elle être retournée avec Drawable? à Kotlin.
Pitos
0

en api niveau 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));
Jaime López Romero
la source
Vous devriez fournir un peu plus de contexte autour de votre réponse.
Nicolas Grenié
0

Maintenant, vous devez implémenter comme ça

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
        //
    } else {
        //
    }

Suivre une seule ligne de code suffit, tout sera pris en charge par ContextCompat.getDrawable

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)
Farid Haq
la source
0

Pour certains qui ont encore ce problème à résoudre même après avoir appliqué la suggestion de ce fil (j'en étais un comme ça), ajoutez cette ligne à votre classe Application, méthode onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Comme suggéré ici et ici, cela est parfois nécessaire pour accéder aux vecteurs à partir des ressources, en particulier lorsque vous avez affaire à des éléments de menu, etc.

Stamatis Stiliats
la source
0

Dans Kotlin, vous pouvez utiliser l'extension

fun Context.getMyDrawable(id : Int) : Drawable?{

    return  ContextCompat.getDrawable(this, id)
}

puis utilisez comme

context.getMyDrawable(R.drawable.my_icon)
Deepak Kanyan
la source
-2

Build.VERSION_CODES.LOLLIPOP devrait maintenant être remplacé par BuildVersionCodes.Lollipop, c'est-à-dire:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}
Ryan Herman
la source
N'est-ce pas BuildVersionCodesune classe spécifique à Xamarin?
Ted Hopp