getColor (int id) przestarzałe w systemie Android 6.0 Marshmallow (API 23)

718

Resources.getColor(int id)Metoda została zaniechana.

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

Co powinienem zrobić?

araks
źródło
26
Użyj ContextCompat.getColor (kontekst, nazwa_koloru.koloru)
Ashokchakravarthi Nagarajan
Za pomocą tej metody wspomnianej powyżej: getColor (kontekst, R.color.your_color); Nie jest jasne, jak uzyskać „kontekst”. To nie zadziała, po prostu umieszczając tam kontekst w moim przypadku, Android Studio 3.2. Uważam, że to działa dla mnie. .setTextColor (Color.RED).
Harry

Odpowiedzi:

1347

Począwszy od Androida Wsparcia Biblioteki 23,
nowy GetColor () metoda został dodany do ContextCompat.

Jego opis z oficjalnego JavaDoc:

Zwraca kolor powiązany z określonym identyfikatorem zasobu

Począwszy od M, zwracany kolor będzie stylizowany dla określonego motywu kontekstu.


Więc po prostu zadzwoń :

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


Możesz sprawdzić ContextCompat.getColor() kod źródłowy na GitHub .

araks
źródło
1
To wygląda na rozwiązanie, ale co powinniśmy zrobić, gdy pojawia się błąd „Czy należy przekazać tutaj rozstrzygnięty kolor zamiast identyfikatora zasobu”? O ile wiem, to prawdopodobnie dlatego, że Lint nie rozpoznaje nowego API biblioteki wsparcia, więc może wystarczy dodać adnotację @SuppressWarnings („ResourceAsColor”)? Nie podoba mi się to jednak.
Stan
1
Cześć @Stan, czy możesz podać fragment kodu z wywołaniem metody, która wyzwala Lint „ResourceAsColor”?
araks 15.03.16
„int color = ContextCompat.getColor (this, R.color.orange);” a następnie „span = new ForegroundColorSpan (color);”. Słowo, które jest podkreślone na czerwono to „kolor”, gdzie przekazuję je do „new ForegroundColorSpan ()”.
Stan
1
@MonicaLabbao och ... przepraszam, źle zrozumiałem twój komentarz! :)
araks
3
ContextCompatApi23 ten błąd znaku zakładał, że odwołujesz się ContextCompat
Webserveis,
498

tl; dr:

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

Wyjaśnienie:

Będziesz musiał użyć ContextCompat.getColor () , który jest częścią biblioteki Support V4 (będzie działać dla wszystkich poprzednich interfejsów API).

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

Jeśli jeszcze nie korzystasz z biblioteki wsparcia, musisz dodać następujący wiersz do dependenciestablicy w aplikacji build.gradle(uwaga: jest to opcjonalne, jeśli już korzystasz z biblioteki appcompat (V7) ):

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

Jeśli zależy Ci na motywach, dokumentacja określa, że:

Począwszy od M, zwracany kolor będzie stylizowany dla określonego motywu kontekstu

Melvin
źródło
4
To powinna być wybrana jako poprawna odpowiedź. Ponieważ w danym ogniwie Android Docs, to powiedzieć „ Począwszy od M, zwrócony kolor będzie stylizowany na temat określonego kontekstu w.
Bugs Happen
1
skompiluj „com.android.support:appcompat-v7:23.0.1”
G O'Rilla
@G O'Rilla Jak widać w dokumentacji, ContextCompatklasa pochodzi z SupportV4. AppcompatV7 również działa, ponieważ opiera się na SupportV4. Jak mówią w dokumentacji biblioteki Pomoc , 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.. Dlatego nie ma sensu udzielać AppcompatV7odpowiedzi.
Melvin,
1
Dzięki @Melvin, oto mój przykład użycia: 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. Co to dokładnie znaczy, że „kolor zostanie nadany stylowi do określonego motywu kontekstu”. Wygląda na to, że w zależności od motywu można zdefiniować różne kolory dla tego samego identyfikatora koloru. Jak to się dokładnie robi?
RobertoCuba,
47

Nie chcę dołączać biblioteki wsparcia tylko dla getColor , więc używam czegoś takiego

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

Myślę, że kod powinien działać dobrze, a przestarzałe getColornie może zniknąć z API <23.

I tego właśnie używam w Kotlinie:

/**
 * 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
źródło
4
Patrząc na kod źródłowy, dokładnie tak robi biblioteka obsługi. Kieruję API> = 21, więc nie chcę dołączać pełnego jar dla tych kilku wierszy. Pamiętaj, że możesz wyłączyć ostrzeżenie w Android Studio, dodając „// przestarzałe wycofanie” powyżej przestarzałego wywołania. I użyj kontekstu działania, a nie kontekstu aplikacji, w przeciwnym razie możesz utracić informacje o motywie.
personne3000,
2
To powinna być prawidłowa odpowiedź, chociaż biblioteka wsparcia może być wyborem przyszłościowym, zgadzam się, że jeśli jest to jedyny powód, dla którego umieścisz bibliotekę wsparcia, lepiej dołącz te kilka wierszy.
anthonymonori,
30

W systemie Android Marshmallow wiele metod jest przestarzałych.

Na przykład, aby uzyskać kolor

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

Również, aby uzyskać możliwość rysowania

ContextCompat.getDrawable(context, R.drawable.drawble_name);
Ashokchakravarthi Nagarajan
źródło
3
skąd pochodzi kontekst zmienny? czy muszę to zainicjować? Nie mogę zmusić go do pracy. Wydaje mi się, że Androind ma przed sobą długą drogę; wieje mój umysł, jak bardzo staram się uzyskać kolor z zasobu xml !! Wow
ColdTuna,
29

Dla wszystkich użytkowników Kotlin:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}
Paul Spiesberger
źródło
Właściwie powinno być val color = ContextCompat.getColor(context, R.color.colorPrimary). Zmienna „it” może być dowolna, ale musi być kontekstem .
Scott Biggs,
itjest w tym przypadku context, ponieważ używam context?.let {do sprawdzenia, czy contextnie jest zerowa. Funkcja getColor()akceptuje tylko kontekst inny niż null. Przeczytaj więcej o tym leti jak z niego korzystać: kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger
4

W swoim urządzeniu do recyklingu Zobacz w 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
źródło
1

Skorzystaj z getColor(Resources, int, Theme)metody z ResourcesCompatBiblioteki pomocy technicznej Androida.

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

Myślę, że lepiej odzwierciedlić swoje pytanie niż getColor(Context, int)z ContextCompatskoro pytasz o Resources. Przed wersją interfejsu API poziomu 23 motyw nie zostanie zastosowany, a metoda wywoła funkcję, getColor(int)ale nie będzie już przestarzałe ostrzeżenie. Temat może być również null.

Pedro
źródło
1
Jeśli jako argument Motyw podasz null, zwracany kolor NIE zostanie nadany styl dla bieżącego motywu. Może to być niepoprawne.
araks
1

Jeśli niekoniecznie potrzebujesz zasobów, użyj parseColor(String):
Color.parseColor("#cc0066")

N. Osil
źródło
1

Jeśli twój obecny min. Poziom interfejsu API to 23, możesz po prostu używaćgetColor() tak, jak my, aby uzyskać zasoby ciągów przez getString():

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

Możesz ograniczyć poziomy API poniżej 23:

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

ale dla uproszczenia możesz zrobić jak poniżej, jako zaakceptowaną odpowiedź:

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

Z zasobów .

Z ContextCompat AndroidX .

Z obsługi ContextCompat

Blasanka
źródło
0

Sfrustrowałem się też. Moja potrzeba była bardzo prosta. Wszystko czego chciałem to kolor ARGB z zasobów, więc napisałem prostą metodę statyczną.

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
źródło