getColor (int id) déconseillé sur Android 6.0 Marshmallow (API 23)

719

La Resources.getColor(int id)méthode est obsolète.

@ColorInt
@Deprecated
public int getColor(@ColorRes int id) throws NotFoundException {
    return getColor(id, null);
}

Que devrais-je faire?

araks
la source
26
Utilisez ContextCompat.getColor (context, R.color.color_name)
Ashokchakravarthi Nagarajan
Avec cette méthode mentionnée ci-dessus: getColor (context, R.color.your_color); Il n'est pas clair comment obtenir le «contexte». Cela ne fonctionnera pas en plaçant simplement le contexte dans mon cas, Android Studio 3.2. Je trouve que cela fonctionne pour moi. .setTextColor (Color.RED).
Harry

Réponses:

1347

À partir de la bibliothèque de support Android 23,
une nouvelle méthode getColor () a été ajoutée à ContextCompat.

Sa description du JavaDoc officiel:

Renvoie une couleur associée à un ID de ressource particulier

À partir de M, la couleur renvoyée sera stylisée pour le thème du contexte spécifié.


Alors, appelez simplement :

ContextCompat.getColor(context, R.color.your_color);


Vous pouvez vérifier le ContextCompat.getColor() code source sur GitHub .

araks
la source
1
Cela ressemble à la solution, mais que sommes-nous censés faire lorsque nous obtenons une erreur «Faut-il passer la couleur résolue au lieu de l'ID de ressource ici»? Pour autant que je sache, c'est probablement parce que Lint ne reconnaît pas la nouvelle API de la bibliothèque de support, alors peut-être qu'il suffit d'ajouter une annotation @SuppressWarnings ("ResourceAsColor")? Mais je n'aime pas trop ça.
Stan
1
Salut @Stan, pouvez-vous s'il vous plaît fournir l'extrait de code avec l'appel de méthode qui déclenche le peluche "ResourceAsColor"?
araks
"int color = ContextCompat.getColor (this, R.color.orange);" puis "span = new ForegroundColorSpan (color);". Le mot qui est souligné en rouge est "couleur" où je le passe à "nouveau ForegroundColorSpan ()".
Stan
1
@MonicaLabbao oh ... désolé, j'ai mal compris votre commentaire! :)
araks
3
ContextCompatApi23 cette erreur de marque vous a suggéré de faire référence à ContextCompat
Webserveis
499

tl; dr:

ContextCompat.getColor(context, R.color.my_color)

Explication:

Vous devrez utiliser ContextCompat.getColor () , qui fait partie de la bibliothèque Support V4 (cela fonctionnera pour toutes les API précédentes).

ContextCompat.getColor(context, R.color.my_color)

Si vous n'utilisez pas déjà la bibliothèque de support, vous devrez ajouter la ligne suivante au dependenciestableau dans votre application build.gradle(remarque: elle est facultative si vous utilisez déjà la bibliothèque appcompat (V7) ):

compile 'com.android.support:support-v4:23.0.0' # or any version above

Si vous vous souciez des thèmes, la documentation précise que:

À partir de M, la couleur renvoyée sera stylisée pour le thème du contexte spécifié

Melvin
la source
4
Cela devrait être la bonne réponse choisie. Parce que dans le lien donné d'Android Docs, il est dit " À partir de M, la couleur retournée sera stylisée pour le thème du contexte spécifié. "
Bugs Happen
1
compiler 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla
@G O'Rilla Comme vous pouvez le voir dans la documentation, la ContextCompatclasse provient de SupportV4. AppcompatV7 fonctionne également car il repose sur SupportV4. Comme on dit sur la documentation de la bibliothèque de soutien , This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.. Il est donc logique de ne pas mettre AppcompatV7la réponse.
Melvin
1
Merci @Melvin, voici mon exemple si utile: int colorTwitterBlue = ContextCompat.getColor (this, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGATIVE) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
Lara Ruffle Coles
1
@Melvin. Qu'est-ce que cela signifie exactement que la «couleur sera stylisée selon le thème du contexte spécifié». On dirait que l'on peut définir différentes couleurs pour le même identifiant de couleur selon le thème. Comment cela se fait-il exactement?
RobertoCuba
47

Je ne veux pas inclure la bibliothèque de support uniquement pour getColor , donc j'utilise quelque chose comme

public static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return context.getColor(id);
    } else {
        //noinspection deprecation
        return context.getResources().getColor(id);
    }
}

Je suppose que le code devrait fonctionner très bien et que le code obsolète getColorne peut pas disparaître de l'API <23.

Et voici ce que j'utilise dans Kotlin:

/**
 * Returns a color associated with a particular resource ID.
 *
 * Wrapper around the deprecated [Resources.getColor][android.content.res.Resources.getColor].
 */
@Suppress("DEPRECATION")
@ColorInt
fun getColorHelper(context: Context, @ColorRes id: Int) =
    if (Build.VERSION.SDK_INT >= 23) context.getColor(id) else context.resources.getColor(id);
Alex Vang
la source
4
En regardant le code source, c'est exactement comment la bibliothèque de support le fait. Je cible l'API> = 21, donc je ne veux pas inclure un pot complet pour ces quelques lignes. Notez que vous pouvez supprimer l'avertissement dans Android Studio en ajoutant "// désapprobation noinspection" au-dessus de l'appel obsolète. Et utilisez un contexte d'activité, pas un contexte d'application, sinon vous risquez de perdre des informations sur le thème.
personne3000
2
Cela devrait être la bonne réponse, bien que la bibliothèque de support puisse être un choix plus à l'épreuve du temps, je suis d'accord que si c'est la seule raison pour laquelle vous incluez la bibliothèque de support, vous feriez mieux d'inclure ces deux lignes.
anthonymonori
30

Dans Android Marshmallow, de nombreuses méthodes sont obsolètes.

Par exemple, pour utiliser la couleur

ContextCompat.getColor(context, R.color.color_name);

Aussi pour obtenir une utilisation tirable

ContextCompat.getDrawable(context, R.drawable.drawble_name);
Ashokchakravarthi Nagarajan
la source
3
d'où vient le contexte variable? dois-je l'initialiser? Je n'arrive pas à le faire marcher. Il me semble qu'Androind a encore un long chemin à parcourir; ça me fait foutre à quel point j'ai du mal à obtenir une couleur af à partir d'une ressource xml !! Wow
ColdTuna
29

Pour tous les utilisateurs de Kotlin:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}
Paul Spiesberger
la source
En fait, devrait l'être val color = ContextCompat.getColor(context, R.color.colorPrimary). La variable "it" peut être n'importe quoi, mais elle doit être un contexte .
Scott Biggs
itest dans ce cas le context, puisque j'utilise context?.let {pour vérifier si le contextn'est pas nul. La fonction getColor()accepte uniquement un contexte non nul. En savoir plus ici letet comment l'utiliser: kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger
4

Dans votre RecyclerView à Kotlin

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(t: YourObject, listener: OnItemClickListener.YourObjectListener) = with(itemView) {
        textViewcolor.setTextColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary))
        textViewcolor.text = t.name
    }
}
Irvin Joao
la source
1

Utilisez la getColor(Resources, int, Theme)méthode de la à ResourcesCompatpartir de la bibliothèque de support Android.

int white = new ResourcesCompat().getColor(getResources(), R.color.white, null);

Je pense que cela reflète mieux votre question que celle getColor(Context, int)de la ContextCompatdepuis que vous demandez Resources. Avant le niveau 23 de l'API, le thème ne sera pas appliqué et la méthode appelle getColor(int)mais vous n'aurez pas l'avertissement obsolète. Le thème peut également être null.

Pedro
la source
1
Si vous passez null comme argument Thème, la couleur renvoyée ne sera PAS stylisée pour le thème actuel. Cela peut donc être incorrect.
Araks
1

Si vous n'avez pas nécessairement besoin des ressources, utilisez parseColor(String):
Color.parseColor("#cc0066")

N. Osil
la source
1

Si votre min. Le niveau d'API est 23, vous pouvez simplement utilisergetColor() comme nous utilisons pour obtenir des ressources de chaîne en getString():

//example
textView.setTextColor(getColor(R.color.green));
// if `Context` is not available, use with context.getColor()

Vous pouvez contraindre pour les niveaux d'API inférieurs à 23:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

mais pour rester simple, vous pouvez faire comme ci-dessous la réponse acceptée:

textView.setTextColor(ContextCompat.getColor(context, R.color.green))

Des ressources .

Depuis ContextCompat AndroidX .

Du support ContextCompat

Blasanka
la source
0

Je suis frustré aussi. Mon besoin était très simple. Tout ce que je voulais, c'était la couleur ARGB des ressources, j'ai donc écrit une méthode statique simple.

protected static int getARGBColor(Context c, int resId)
        throws Resources.NotFoundException {

    TypedValue color = new TypedValue();
    try {
        c.getResources().getValue(resId, color, true);
    }
    catch (Resources.NotFoundException e) {
        throw(new Resources.NotFoundException(
                  String.format("Failed to find color for resourse id 0x%08x",
                                resId)));
    }
    if (color.type != TYPE_INT_COLOR_ARGB8) {
        throw(new Resources.NotFoundException(
                  String.format(
                      "Resourse id 0x%08x is of type 0x%02d. Expected TYPE_INT_COLOR_ARGB8",
                      resId, color.type))
        );
    }
    return color.data;
}
Steven Smith
la source