Ottieni color-int dalla risorsa colore


448

C'è un modo per ottenere un color-int da una risorsa color? Sto cercando di ottenere i singoli componenti rosso, blu e verde di un colore definito nella risorsa (R.color.myColor) in modo da poter impostare i valori di tre barre di ricerca su un livello specifico.

Risposte:


928

Puoi usare:

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

Controlla qui su come definire i colori personalizzati:

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

EDIT (1): poiché ora getColor(int id)è obsoleto , deve essere utilizzato:

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

(aggiunto nella libreria di supporto 23)

EDIT (2):

Il codice seguente può essere utilizzato sia per pre che per post Marshmallow (API 23)

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

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme

7
che dire di android.R.color.some_color :-(
Blundell,

17
@Blundell uhh, non so se ne hai bisogno ora ma questo funziona android.R.color.some_coloranche per esempio: getResources().getColor(android.R.color.holo_blue_bright)(almeno, su API 17)
ataulm

30
getColor () è ora obsoleto, è possibile utilizzare: ContextCompat.getColor (context, R.color.your_color);
Ricardo,

2
Mi rendo conto che non sei tu quello che ha apportato le modifiche, ma qual è la differenza tra ContextCompate ResourcesCompat? Se non vi è alcuna differenza pratica, sarebbe meno confuso se ne rimossi uno dalla tua risposta.
Suragch,

14
Perché Google sente la necessità di deprecare una funzione perfettamente valida per quella terribile libreria compatta per app. Fa schifo, hanno entrambi.
Andrew S,

116

Sulla base della nuova libreria di supporto Android (e di questo aggiornamento), ora dovresti chiamare:

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

Secondo la documentazione :

public int getColor (int id)

Questo metodo è stato deprecato nel livello API 23 . Utilizzare invece getColor (int, Theme)

È la stessa soluzione per getResources().getColorStateList(id):

Devi cambiarlo in questo modo:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

Per quanto riguarda l' ThemeOverlayuso del contesto della vista più vicina:

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

Quindi in questo modo ottieni il colore giusto in base al tuo ThemeOverlay.

Necessario specialmente quando nella stessa attività usi temi diversi, come il tema scuro / chiaro. Se vuoi saperne di più su Temi e stili, questo discorso è suggerito: Sviluppare temi con stile

Nick Butcher - Droidcon Berlin - Sviluppare temi con stile


10
Per coloro che si chiedono cosa inserire come tema nel nuovo metodo, Themepuò essere passato come nullo, quindi chiama getColor(R.color.my_color, null)se non sei sicuro di quale tema passare.
w3bshark

hmm ... questo è quello che dicono tutti ma non riesco a farlo funzionare. Devo inizializzare il contesto? Attualmente ottengo "impossibile risolvere il simbolo" contesto ""
ColdTuna,

Per assicurarti di farlo nel modo giusto, prova a chiamarlo all'interno di onCreate dell'attività, piuttosto che per ottenere un contesto devi chiamare getContext () o semplicemente "questo"
Ultimo_m

35

Definisci il tuo colore

Valori / 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>

Ottieni il colore int e impostalo

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);

Guarda anche


1
puoi usare solo getResources()in un Activityo Fragment?
Zapnologica,

2
@Zapnologica, vedi le risposte a questa domanda per pensieri sull'uso getResources()al di fuori di un'attività o di un frammento.
Suragch,

1
@Zapnologica no. getResources()è disponibile anche come API pubblica su tutto ciò che implementa il contesto e anche su Views.
ataulm

7

Il miglior approccio

Come risposta @sat, è un buon approccio per ottenere il colore

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

o usa il metodo seguente quando non hai accesso al getResources()metodo.

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

Quello che faccio è

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

È più semplice da usare ovunque nella tua app! Anche nella classe Util o in qualsiasi altra classe in cui non hai Context o getResource ()

Problema (quando non si ha un contesto)

Quando non hai Contextaccesso , come un metodo nel tuoUtil classe.

Assumi il metodo seguente senza contesto.

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

Ora passerai Contextcome parametro in questo metodo e utilizzeraigetResources().

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

Quindi ecco una soluzione unica di Bonus con cui puoi accedere alle risorse da qualsiasi luogo simile Util class. Aggiungi Resourcesalla tua Applicationclasse o Creane uno se non esiste.

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;
    }

}

Aggiungi il campo del nome al tuo manifest.xml <applicationtag. (Se non aggiunto già)

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

Ora sei a posto. Utilizza ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);ovunque in app.


5

Ho aggiornato per usare ContextCompat.getColor(context, R.color.your_color);ma a volte (su alcuni dispositivi / versioni Android. Non sono sicuro) che causa un NullPointerExcepiton.

Quindi, per farlo funzionare su tutti i dispositivi / versioni, torno sul vecchio modo di farlo, nel caso di un puntatore nullo.

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));
    }
}

perché non usare la versione precedente in tutti i casi, o se stai controllando la versione comunque, Resources.getColor(int, Theme)se puoi puoi usare la nuova API ? Non si dovrebbero intercettare eccezioni di runtime.
ataulm

Solo un disturbo ossessivo compulsivo suppongo. ContextCompat, per me sembra essere il modo a prova di futuro per farlo, e quindi il modo giusto. Quindi il mio approccio è, fallo nel modo giusto. E se fallisce (su vecchi dispositivi o altro), fallo alla vecchia maniera. Perché non dovrei rilevare eccezioni in fase di esecuzione?
ninjachippie,

1

Per ulteriori informazioni su un altro caso d'uso che può aiutare a far emergere questa domanda nei risultati di ricerca, ho voluto applicare l'alfa a un colore definito nelle mie risorse.

Utilizzando la risposta corretta di @ 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)
);

1

Trovato un modo più semplice che funziona anche:

Color.parseColor(getString(R.color.idname);

Interessante, non avevo capito che potresti ottenere il colore come una stringa in questo modo. Non penso sia più facile, ma è interessante 😅
ataulm il

0

L'accesso ai colori da una classe di non attività può essere difficile. Una delle alternative che ho trovato stava usando enum. enumoffre molta flessibilità.

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;
  }
}


0

Se il tuo attuale min. Il livello API è 23, puoi semplicemente usare getColor()come stiamo usando per getString():

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

Se vuoi al di sotto del livello API 23, usa questo:

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

Si noti che getResources().getColor()è obsoleto a livello di API 23. In tal caso, sostituire sopra con:

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

ContextCompat : Helper per l'accesso alle funzioni inContext

Se vuoi, puoi vincolare con SDK_INTcome di seguito:

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

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

in attività

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

in frammento

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

per esempio:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.