застарілий getColor (int id) на Android 6.0 Marshmallow (API 23)


718

Resources.getColor(int id)Метод є застарілим.

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

Що я повинен зробити?


26
Використовуйте ContextCompat.getColor (контекст, R.color.color_name)
Ashokchakravarthi Nagarajan

За допомогою зазначеного вище способу: getColor (контекст, R.color.your_color); Незрозуміло, як отримати "контекст". Це не спрацює, просто поставивши контекст у моєму випадку, android studio 3.2. Я вважаю, що це працює для мене. .setTextColor (Color.RED).
Гаррі

Відповіді:


1347

Починаючи з бібліотеки підтримки Android 23,
до нього додано новий метод getColor ()ContextCompat .

Його опис з офіційного JavaDoc:

Повертає колір, пов'язаний з конкретним ідентифікатором ресурсу

Починаючи з M, повернений колір буде стилізований до заданої теми контексту.


Отже, просто зателефонуйте :

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


Ви можете перевірити ContextCompat.getColor() вихідний код на GitHub .


1
Це виглядає як рішення, але що ми повинні робити, коли ми отримуємо помилку "Чи слід тут передавати вирішений колір замість ідентифікатора ресурсу"? Наскільки я можу сказати, це, мабуть, тому, що Lint не розпізнає новий API бібліотеки підтримки, тож можливо просто додавати примітку @SuppressWarnings ("ResourceAsColor")? Мені це дуже не подобається.
Стен

1
Привіт @Stan, чи можете ви надати фрагмент коду з викликом методу, який запускає "Ресурс" ResourceAsColor "?
аракс

"int color = ContextCompat.getColor (це, R.color.orange);" а потім "span = новий ForegroundColorSpan (колір);". Слово, яке підкреслюється червоним кольором, є "кольором", де я передаю його "новому ForegroundColorSpan ()".
Стен

1
@MonicaLabbao о ... вибачте, я неправильно зрозумів ваш коментар! :)
аракс

3
ContextCompatApi23 ця помилка позначила, що ви посилаєтесь ContextCompat
Webserveis

498

tl; dr:

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

Пояснення:

Вам потрібно буде використовувати ContextCompat.getColor () , який є частиною бібліотеки підтримки V4 (він буде працювати для всіх попередніх API).

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

Якщо ви вже не використовуєте Бібліотеку підтримки, вам потрібно буде додати наступний рядок до dependenciesмасиву всередині додатка build.gradle(зверніть увагу: це необов'язково, якщо ви вже використовуєте бібліотеку appcompat (V7) ):

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

Якщо вам важлива тема, у документації зазначено, що:

Починаючи з M, повернений колір буде стилізований до заданої теми контексту


4
Це має бути обрана як правильна відповідь. Тому що в даному ланці Android Docs, це сказати : « Починаючи з M, що повертається колір буде стиль для теми зазначеного контексту ст. »
Помилки трапляються

1
компілювати 'com.android.support:appcompat-v7:23.0.1'
G O'Rilla

@G O'Rilla Як ви бачите в документації, ContextCompatклас походить від SupportV4. AppcompatV7 також працює, оскільки покладається на SupportV4. Як говориться в документації бібліотеки підтримки , 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.. Тож є сенс не ставити AppcompatV7у відповідь.
Мелвін

1
Дякую @Melvin, ось мій приклад, якщо використовується: int colorTwitterBlue = ContextCompat.getColor (це, R.color.color_twitter_blue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_NEGATIVE) .setTextColor (colorTwitterBlue); composeTweetAlertDialog.getButton (AlertDialog.BUTTON_POSITIVE) .setTextColor (colorTwitterBlue);
Lara Ruffle Coles

1
@Melvin. Що саме означає, що "колір буде стилізований до заданої теми контексту". Звучить, що один може визначати різні кольори для одного і того ж ідентифікатора кольору залежно від теми. Як це робиться саме?
RobertoCuba

47

Я не хочу включати бібліотеку підтримки лише для getColor , тому я використовую щось на зразок

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

Я думаю, що код повинен працювати чудово, і застарілий не getColorможе зникнути з API <23.

І ось що я використовую в Котліні:

/**
 * 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
Дивлячись на вихідний код, саме так це робить бібліотека підтримки. Я націлюю API> = 21, тому я не хочу включати повну банку для цих кількох рядків. Зауважте, що ви можете придушити попередження в Android Studio, додавши "// noprepection deprecation" над застарілим викликом. І використовуйте контекст діяльності, а не контекст програми, або ви можете втратити інформацію про теми.
personne3000

2
Це має бути правильною відповіддю, хоча бібліотека підтримки може бути більш перспективним вибором, я погоджуюся, що якщо це єдина причина, для якої ви включите бібліотеку підтримки, вам краще включити ці пару рядків.
антомонорі

30

В Android Marshmallow багато методів застаріли.

Наприклад, для використання кольору

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

Також отримати драматичне використання

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

3
звідки походить змінний контекст? чи потрібно його ініціалізувати? Я не можу змусити його працювати. Мені здається, що у Андроїда ще довгий шлях; це дує мій розум, як багато я борюся, щоб отримати колір з ресурсу XML !! Нічого собі
ColdTuna

29

Для всіх користувачів Kotlin там:

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

Насправді має бути val color = ContextCompat.getColor(context, R.color.colorPrimary). Змінна "вона" може бути будь-якою, але вона повинна бути контекстом .
Скотт Біггс

itв цьому випадку це context, оскільки я використовую, context?.let {щоб перевірити, чи contextне є нульовим. Функція getColor()приймає лише ненульовий контекст. Детальніше читайте тут про letта як ним користуватися: kotlinlang.org/docs/reference/scope-functions.html#let
Пол Шпієбергер

4

У вашому RecyclerView у Котліні

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

Скористайтеся getColor(Resources, int, Theme)методом з ResourcesCompatбібліотеки підтримки Android.

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

Я думаю, що це краще відображає ваше питання, ніж те, getColor(Context, int)з тих ContextCompatпір, про яке ви питаєте Resources. До рівня 23 інтерфейсу API тема не застосовуватиметься, і метод викликає, getColor(int)але ви не будете мати застаріле попередження. Тема також може бути null.


1
Якщо ви передасте null як аргумент теми, повернутий колір НЕ буде стилізований до поточної теми. Тож це може бути неправильно.
аракс


1

Якщо ваш поточний хв. Рівень API - 23, ви можете просто використовувати так,getColor() як ми використовуємо для отримання рядкових ресурсів getString():

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

Ви можете обмежити рівні API нижче 23:

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

але щоб це було просто, ви можете зробити наступне, як прийнята відповідь:

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

З ресурсів .

Від ContextCompat AndroidX .

Від підтримки ContextCompat


0

Я теж розчарувався. Моя потреба була дуже очевидною. Все, що я хотів, - це колір ARGB з ресурсів, тому я написав простий статичний метод.

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.