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


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.