Obtenez color-int de ressource de couleur

448

Existe-t-il un moyen d'obtenir un color-int à partir d'une ressource de couleur? J'essaie d'obtenir les composants rouges, bleus et verts individuels d'une couleur définie dans la ressource (R.color.myColor) afin de pouvoir définir les valeurs de trois barres de recherche à un niveau spécifique.

ataulm
la source

Réponses:

928

Vous pouvez utiliser:

getResources().getColor(R.color.idname);

Vérifiez ici comment définir des couleurs personnalisées:

http://sree.cc/google/android/defining-custom-colors-using-xml-in-android

EDIT (1): Puisque getColor(int id)est obsolète maintenant, il doit être utilisé:

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

(ajouté dans la bibliothèque de support 23)

MODIFIER (2):

Le code ci-dessous peut être utilisé à la fois avant et après la guimauve (API 23)

ResourcesCompat.getColor(getResources(), R.color.your_color, null); //without theme

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme
Sam
la source
7
Qu'en est-il de android.R.color.some_color :-(
Blundell
17
@Blundell euh, ne sais pas si vous en avez besoin maintenant, mais cela fonctionne android.R.color.some_coloraussi, par exemple: getResources().getColor(android.R.color.holo_blue_bright)(au moins, sur API 17)
ataulm
30
getColor () est désormais obsolète, vous pouvez utiliser: ContextCompat.getColor (context, R.color.your_color);
Ricardo
2
Je me rends compte que ce n'est pas vous qui avez fait les modifications, mais quelle est la différence entre ContextCompatet ResourcesCompat? S'il n'y a pas de différence pratique, ce serait moins déroutant si vous supprimiez l'un d'eux de votre réponse.
Suragch
14
Pourquoi Google ressent-il le besoin de déconseiller une fonction parfaitement bonne pour cette horrible bibliothèque compacte d'applications. Ça craint, avoir les deux.
Andrew S
116

Basé sur la nouvelle bibliothèque de support Android (et cette mise à jour), vous devez maintenant appeler:

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

Selon la documentation :

public int getColor (int id)

Cette méthode est déconseillée au niveau API 23 . Utilisez getColor (int, Theme) à la place

C'est la même solution pour getResources().getColorStateList(id):

Vous devez le changer comme ceci:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

Concernant l' ThemeOverlayutilisation du contexte de la vue la plus proche:

val color = ContextCompat.getColor(
  closestView.context,
  R.color.name.color
)

Ainsi, vous obtenez la bonne couleur en fonction de votre ThemeOverlay.

Particulièrement nécessaire lorsque dans la même activité, vous utilisez différents thèmes, comme le thème sombre / clair. Si vous souhaitez en savoir plus sur les thèmes et les styles, cette présentation est suggérée: Développement de thèmes avec style

Nick Butcher - Droidcon Berlin - Développer des thèmes avec style

Ultimo_m
la source
10
Pour ceux qui se demandent quoi remplir en tant que thème dans la nouvelle méthode, Themepeut être passé comme nul, alors appelez simplement getColor(R.color.my_color, null)si vous ne savez pas quel thème passer.
w3bshark
hmm ... c'est ce que tout le monde dit mais je ne peux pas le faire fonctionner. Dois-je initialiser le contexte? Actuellement, je reçois "ne peut pas résoudre le symbole" contexte ""
ColdTuna
Pour vous assurer que vous le faites correctement, essayez de l'appeler dans le onCreate de l'activité, que pour obtenir le contexte, vous devez appeler getContext () ou simplement "this"
Ultimo_m
35

Définissez votre couleur

values ​​/ color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- color int as #AARRGGBB (alpha, red, green, blue) -->
    <color name="orange">#fff3632b</color>
    ...
    <color name="my_view_color">@color/orange</color>

</resources>

Obtenez la couleur et définissez-la

int backgroundColor = ContextCompat.getColor(context, R.color.my_view_color);
// Color backgroundColor = ... (Don't do this. The color is just an int.)

myView.setBackgroundColor(backgroundColor);

Voir également

Suragch
la source
1
pouvez-vous utiliser uniquement getResources()dans un Activityou Fragment?
Zapnologica
2
@Zapnologica, voir les réponses à cette question pour des réflexions sur l'utilisation en getResources()dehors d'une activité ou d'un fragment.
Suragch
1
@Zapnologica no. getResources()est également disponible en tant qu'API publique sur tout ce qui implémente le contexte et également sur les vues.
ataulm
7

Meilleure approche

Comme réponse @sat, une bonne approche pour obtenir des couleurs est

ResourcesCompat.getColor(getResources(), R.color.your_color, null);

ou utilisez ci-dessous lorsque vous n'avez pas accès à la getResources()méthode.

Context context  = getContext(); // like Dialog class
ResourcesCompat.getColor(context.getResources(), R.color.your_color, null);

Ce que je fais c'est

public void someMethod(){
    ...
    ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);
}

Il est plus simple à utiliser n'importe où dans votre application! Même dans la classe Util ou dans toute classe où vous n'avez pas Context ou getResource ()

Problème (lorsque vous n'avez pas de contexte)

Lorsque vous n'y avez pas Contextaccès , comme une méthode dans votre Utilclasse.

Supposons la méthode ci-dessous sans contexte.

public void someMethod(){
    ...
    // can't use getResource() without Context.
}

Vous allez maintenant passer Contextcomme paramètre dans cette méthode et utilisergetResources().

public void someMethod(Context context){
    ...
    context.getResources...
}

Voici donc une solution unique en bonus grâce à laquelle vous pouvez accéder à des ressources de n'importe où Util class. Ajoutez Resourcesà votre Applicationclasse ou créez-en un s'il n'existe pas.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static App mInstance;
    private static Resources res;


    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        res = getResources();
    }

    public static App getInstance() {
        return mInstance;
    }

    public static Resources getResourses() {
        return res;
    }

}

Ajoutez un champ de nom à votre manifest.xml <applicationbalise. (Si pas déjà ajouté)

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Vous êtes maintenant prêt à partir. Utilisez ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);n'importe où dans l'application.

Khemraj
la source
5

J'ai mis à jour pour utiliser ContextCompat.getColor(context, R.color.your_color);mais parfois (sur certains appareils / versions Android. Je ne suis pas sûr) cela provoque un NullPointerExcepiton.

Donc, pour le faire fonctionner sur tous les appareils / versions, je retombe sur l'ancienne façon de le faire, dans le cas d'un pointeur nul.

try {
    textView.setTextColor(ContextCompat.getColor(getActivity(), R.color.text_grey_dark));
}
catch(NullPointerException e) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        textView.setTextColor(getContext().getColor(R.color.text_grey_dark));
    }
    else {
        textView.setTextColor(getResources().getColor(R.color.text_grey_dark));
    }
}
ninjachippie
la source
pourquoi ne pas utiliser l'ancienne version dans tous les cas, ou si vous vérifiez quand même la version, utilisez la nouvelle API Resources.getColor(int, Theme)si vous le pouvez? Vous ne devez pas intercepter les exceptions d'exécution.
ataulm
Juste OCD je suppose. ContextCompat, me semble être la façon de le faire à l'épreuve du temps, et donc la bonne façon. Donc, mon approche est de le faire de la bonne façon. Et si cela échoue (sur les anciens appareils ou autre), faites-le à l'ancienne. Pourquoi ne devrais-je pas intercepter des exceptions lors de l'exécution?
ninjachippie
1

Pour plus d'informations sur un autre cas d'utilisation qui pourrait aider à faire apparaître cette question dans les résultats de recherche, je voulais appliquer l'alpha à une couleur définie dans mes ressources.

En utilisant la bonne réponse de @ sat:

int alpha = ... // 0-255, calculated based on some business logic
int actionBarBackground = getResources().getColor(R.color.actionBarBackground);
int actionBarBackgroundWithAlpha = Color.argb(
        alpha,
        Color.red(actionbarBackground),
        Color.green(actionbarBackground),
        Color.blue(actionbarBackground)
);
ataulm
la source
1

Trouvé un moyen plus simple qui fonctionne aussi:

Color.parseColor(getString(R.color.idname);
geckoflume
la source
Intéressant, je ne savais pas que vous pouviez obtenir la couleur sous forme de chaîne de cette manière. Je ne pense pas que ce soit plus facile, mais c'est intéressant 😅
ataulm
0

L'accès aux couleurs d'une classe non active peut être difficile. L'une des alternatives que j'ai trouvées utilisait enum. enumoffre beaucoup de flexibilité.

public enum Colors
{
  COLOR0(0x26, 0x32, 0x38),    // R, G, B
  COLOR1(0xD8, 0x1B, 0x60),
  COLOR2(0xFF, 0xFF, 0x72),
  COLOR3(0x64, 0xDD, 0x17);


  private final int R;
  private final int G;
  private final int B;

  Colors(final int R, final int G, final int B)
  {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public int getColor()
  {
    return (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff);
  }

  public int getR()
  {
    return R;
  }

  public int getG()
  {
    return G;
  }

  public int getB()
  {
    return B;
  }
}
Embrouiller
la source
0

Méthode de travail la plus récente:

getColor(R.color.snackBarAction)
zohaib Ansari
la source
0

Si votre min. Le niveau API est 23, vous pouvez simplement utiliser getColor()comme nous utilisons pour getString():

//example
textView.setTextColor(getColor(R.color.green));
// if context is not available(ex: not in activity) use with context.getColor()

Si vous voulez en dessous du niveau API 23, utilisez simplement ceci:

textView.setTextColor(getResources().getColor(R.color.green));

Mais notez que getResources().getColor()c'est obsolète dans le niveau API 23. Dans ce cas, remplacez ci-dessus par:

textView.setTextColor(ContextCompat.getColor(this /*context*/, R.color.green)) //Im in an activity, so I can use `this`

ContextCompat : Aide pour accéder aux fonctionnalités deContext

Si vous voulez, vous pouvez contraindre avec SDK_INTcomme ci-dessous:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}
Blasanka
la source
0
ContextCompat.getColor(context, R.color.your_color);

en activité

ContextCompat.getColor(actvityname.this, R.color.your_color);

en fragment

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

par exemple:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
indrajeet jyoti
la source