getColor (int id) deprecato su Android 6.0 Marshmallow (API 23)


719

Il Resources.getColor(int id)metodo è stato deprecato.

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

Cosa dovrei fare?


26
Usa ContextCompat.getColor (context, R.color.color_name)
Ashokchakravarthi Nagarajan

Con questo metodo sopra menzionato: getColor (context, R.color.your_color); Non è chiaro come ottenere il "contesto". Non funzionerà semplicemente inserendo il contesto nel mio caso, Android Studio 3.2. Trovo che questo funzioni per me. .setTextColor (Color.RED).
Harry,

Risposte:


1347

A partire dalla libreria di supporto Android 23, è stato aggiunto
un nuovo metodo getColor ()ContextCompat .

La sua descrizione dal JavaDoc ufficiale:

Restituisce un colore associato a un particolare ID risorsa

A partire da M, il colore restituito verrà disegnato in base al tema del contesto specificato.


Quindi, basta chiamare :

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


Puoi controllare il ContextCompat.getColor() codice sorgente su GitHub .


1
Questa sembra la soluzione, ma cosa dovremmo fare quando viene visualizzato un errore "Dovrebbe passare il colore risolto anziché l'ID risorsa qui"? Per quanto ne so, probabilmente è perché Lint non riconosce la nuova API della libreria di supporto, quindi forse è sufficiente aggiungere un'annotazione @SuppressWarnings ("ResourceAsColor")? Non mi piace molto però.
Stan,

1
Ciao @Stan, puoi fornire allo snippet di codice la chiamata del metodo che attiva il Lint "ResourceAsColor"?
Arabi

"int color = ContextCompat.getColor (this, R.color.orange);" e poi "span = new ForegroundColorSpan (color);". La parola sottolineata in rosso è "color" dove la passo a "new ForegroundColorSpan ()".
Stan,

1
@MonicaLabbao oh ... scusa, ho frainteso il tuo commento! :)
arabi,

3
ContextCompatApi23 questo errore di contrassegno ha superato il riferimento ContextCompat
Webserveis

499

tl; dr:

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

Spiegazione:

Dovrai utilizzare ContextCompat.getColor () , che fa parte della libreria Support V4 (funzionerà per tutte le API precedenti).

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

Se non si utilizza già la libreria di supporto, sarà necessario aggiungere la seguente riga dependenciesall'array all'interno dell'app build.gradle(nota: è facoltativo se si utilizza già la libreria appcompat (V7) ):

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

Se ti interessano i temi, la documentazione specifica che:

A partire da M, il colore restituito verrà disegnato in base al tema del contesto specificato


4
Questa dovrebbe essere la risposta selezionata corretta. Perché nel link indicato di Documenti Android, si dice " A partire da M, il colore restituito sarà disegnato per il tema del contesto specificato " .
Bugs Happen

1
compilare 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla,

@G O'Rilla Come puoi vedere nella documentazione, la ContextCompatclasse proviene da SupportV4. AppcompatV7 funziona anche in quanto si basa su SupportV4. Come si dice sulla documentazione di libreria di supporto , 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.. Quindi ha senso non dare AppcompatV7la risposta.
Melvin,

1
Grazie @Melvin, ecco il mio esempio se 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. Che cosa significa esattamente che il "colore sarà adattato al tema del contesto specificato". Sembra che uno possa definire colori diversi per lo stesso ID colore a seconda del tema. Come viene fatto esattamente?
RobertoCuba,

47

Non voglio includere la libreria di supporto solo per getColor , quindi sto usando qualcosa di simile

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

Immagino che il codice dovrebbe funzionare bene e il deprecato getColornon può scomparire dall'API <23.

E questo è quello che sto usando in 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);

4
Guardando il codice sorgente, questo è esattamente come lo fa la libreria di supporto. Targeting API> = 21, quindi non voglio includere un barattolo pieno per queste poche righe. Tieni presente che puoi eliminare l'avviso in Android Studio aggiungendo "// deprecazione noinspection" sopra la chiamata deprecata. E usa un contesto Activity, non un contesto Application, altrimenti potresti perdere le informazioni sul tema.
personne3000,

2
Questa dovrebbe essere la risposta corretta, anche se la libreria di supporto può essere una scelta più a prova di futuro, sono d'accordo che se questa è l'unica ragione per cui includi la libreria di supporto, è meglio includere queste due righe.
anthonymonori,

30

In Android Marshmallow molti metodi sono obsoleti.

Ad esempio, per ottenere l'uso del colore

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

Anche per ottenere un uso disegnabile

ContextCompat.getDrawable(context, R.drawable.drawble_name);

3
da dove viene il contesto variabile? devo inizializzarlo? Non riesco a farlo funzionare. A me sembra che Androind abbia ancora molta strada da fare; mi fa impazzire quanto sto lottando per ottenere un colore da una risorsa XML !! Wow
ColdTuna,

29

Per tutti gli utenti di Kotlin là fuori:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}

In realtà dovrebbe essere val color = ContextCompat.getColor(context, R.color.colorPrimary). La variabile "it" potrebbe essere qualsiasi cosa, ma deve essere un contesto .
Scott Biggs,

itè in questo caso il context, poiché utilizzo context?.let {per verificare se contextnon è null. La funzione getColor()accetta solo un contesto non nullo. Per saperne di più qui lete come usarlo: kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger,

4

In Your RecyclerView in 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
    }
}

1

Utilizzare il getColor(Resources, int, Theme)metodo della ResourcesCompatdalla libreria di supporto Android.

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

Penso che rifletta meglio la tua domanda rispetto a quella getColor(Context, int)di ContextCompatquando chiedi Resources. Prima del livello API 23, il tema non verrà applicato e il metodo verrà richiamato getColor(int)ma non avrai l'avviso deprecato. Il tema potrebbe anche essere null.


1
Se si passa a null come argomento Tema, il colore restituito NON verrà assegnato al tema corrente. Quindi potrebbe non essere corretto.
arabi,


1

Se il tuo attuale min. Il livello API è 23, puoi semplicemente usaregetColor() come stiamo usando per ottenere risorse di stringa getString():

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

Puoi limitare i livelli API inferiori a 23:

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

ma per mantenerlo semplice, puoi fare come di seguito come risposta accettata:

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

Dalle risorse .

Da ContextCompat AndroidX .

Dal supporto ContextCompat


0

Mi sono anche frustrato. Il mio bisogno era molto semplice. Tutto quello che volevo era il colore ARGB dalle risorse, quindi ho scritto un semplice metodo statico.

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