Отримайте кольоровий інт з кольорового ресурсу


448

Чи є спосіб отримати кольоровий int з кольорового ресурсу? Я намагаюся отримати окремі червоні, сині та зелені компоненти кольору, визначені в ресурсі (R.color.myColor), щоб я міг встановити значення трьох панелей пошуку на конкретний рівень.

Відповіді:


928

Ви можете використовувати:

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

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

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

EDIT (1): оскільки getColor(int id)тепер застаріло , це потрібно використовувати:

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

(додано в бібліотеку підтримки 23)

EDIT (2):

Нижче код може використовуватися як до, так і після публікації зефіру (API 23)

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

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

7
як щодо android.R.color.some_color :-(
— Блонделл

17
@Blundell uhh, не знаю, якщо вам це потрібно зараз, але це android.R.color.some_colorтеж працює, наприклад: getResources().getColor(android.R.color.holo_blue_bright)(принаймні, на API 17)
— ataulm

30
getColor () тепер застарілий, ви можете використовувати: ContextCompat.getColor (контекст, R.color.your_color);
— Рікардо

2
Я усвідомлюю, що ти не той, хто вносив зміни, але в чому різниця між ContextCompatі ResourcesCompat? Якщо практичної різниці немає, було б менш заплутано, якби ви видалили один із них зі своєї відповіді.
— Сурагч

14
Чому Google відчуває необхідність знехтувати ідеально гарну функцію для цієї жахливої ​​компактної бібліотеки додатків. Це смокче, є і те, і інше.
— Андрій S

116

На основі нової бібліотеки підтримки Android (і цього оновлення) тепер вам слід зателефонувати:

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

Відповідно до документації :

public int getColor (int id)

Цей метод був застарілий у рівні 23 API . Використовуйте замість getColor (int, Theme)

Це те саме рішення для getResources().getColorStateList(id):

Ви повинні змінити це так:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

Щодо ThemeOverlayвикористання контексту найближчого перегляду:

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

Таким чином ви отримаєте потрібний колір на основі вашої ThemeOverlay.

Особливо потрібно, коли в одній діяльності ви використовуєте різні теми, наприклад темну / світлу тему. Якщо ви хочете дізнатися більше про теми та стилі, пропонується ця розмова: Розробка тем зі стилем

Нік М'ясник - Droidcon Berlin - Розробка тем зі стилем


10
Для тих, хто цікавиться, що заповнити як тему в новому методі, Themeможна пропустити як нуль, тому просто зателефонуйте, getColor(R.color.my_color, null)якщо ви не впевнені, яку тему передати.
— w3bshark

хм ... це все кажуть, але я не можу змусити його працювати. Чи потрібно ініціалізувати контекст? В даний час я отримую "не вдається вирішити символ" контексту ""
— ColdTuna

Щоб переконатися, що ви все робите правильно, спробуйте зателефонувати всередину onCreate діяльності, ніж щоб отримати контекст, вам потрібно зателефонувати getContext () або просто "це"
— Ultimo_m

35

Визначте свій колір

значення / 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>

Отримайте колір int та встановіть його

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

Дивись також


1
ви можете використовувати лише getResources()в Activityабо Fragment?
— Zapnologica

2
@Zapnologica, див. Відповіді на це запитання щодо думок про використання getResources()поза діяльністю чи фрагментом.
— Сурагч

1
@Zapnologica немає. getResources()також доступний як публічний API для будь-якого реалізуючого контексту, а також для переглядів.
— атаульм

7

Кращий підхід

Як @sat відповідь, хороший підхід до отримання кольору

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

або використовувати нижче, коли у вас немає доступу до getResources()методу.

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

Що я роблю, так і є

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

Це найпростіше використовувати в будь-якому місці вашого додатка! Навіть у класі Util або будь-якому класі, де у вас немає Context або getResource ()

Проблема (коли у вас немає контексту)

Коли у вас немає Contextдоступу , як метод у вашому Utilкласі.

Припустимо нижче метод без контексту.

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

Тепер ви перейдете Contextяк параметр у цьому методі та використаєтеgetResources().

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

Отже, ось унікальне бонусне рішення, за допомогою якого ви можете отримати доступ до ресурсів з будь-якого місця Util class. Додайте Resourcesдо свого Applicationкласу або Створіть його, якщо його немає.

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

}

Додайте поле до імені до свого manifest.xml <applicationтегу. (Якщо вже не додано)

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

Тепер вам добре піти. Використовуйте ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);будь-де в додатку.


5

Я оновлювався для використання, ContextCompat.getColor(context, R.color.your_color);але іноді (на деяких пристроях / версіях Android. Я не впевнений), що викликає NullPointerExcepiton.

Таким чином, щоб змусити його працювати на всіх пристроях / версіях, я повертаюся до старого способу цього, у разі нульового вказівника.

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

чому б не використовувати стару версію у всіх випадках, або якщо ви все-таки перевіряєте її, скористайтеся новим API, Resources.getColor(int, Theme)якщо зможете? Ви не повинні ловити винятки з виконання.
— ataulm

Просто OCD я гадаю. Мені здається, ContextCompat є майбутнім доказовим способом його виконання, а отже, правильним. Тож мій підхід - робити це правильно. А якщо це не вдається (на старих пристроях чи будь-яких інших), зробіть це по-старому. Чому я не можу ловити винятки під час виконання?
— ninjachippie

1

Для отримання додаткової інформації про інший випадок використання, який може допомогти вирішити це питання в результатах пошуку, я хотів застосувати альфа до кольору, визначеного в моїх ресурсах.

Використовуючи правильну відповідь @ 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

Знайдений простіший спосіб роботи:

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

Цікаво, що не зрозумів, що ти можеш отримати колір у вигляді рядка таким чином. Я не думаю, що це простіше, але це цікаво a
— ataulm

0

Доступ до кольорів з заняття без активності може бути важким. Однією з альтернатив, яку я знайшов, було використання enum. enumпропонує велику гнучкість.

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

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

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

Якщо ви хочете нижче рівня API 23, просто використовуйте це:

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

Але зауважте, що getResources().getColor()це застаріло в рівні API 23. У цьому випадку замініть вище на:

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

ContextCompat : Помічник для доступу до функцій уContext

Якщо ви хочете, ви можете обмежитись, SDK_INTяк описано нижче:

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

у діяльності

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

у фрагменті

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

наприклад:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.