Программно заданный цвет текста для основного андроида

Как я могу установить цвет текста моего TextView на ?android:textColorPrimary программно?

Я пробовал код ниже, но он устанавливает цвет текста всегда в белый как для textColorPrimary, так и для textColorPrimaryInverse (оба из них не белые, я проверил XML).

TypedValue typedValue = new TypedValue();
Resources.Theme theme = getActivity().getTheme();
theme.resolveAttribute(android.R.attr.textColorPrimaryInverse, typedValue, true);
int primaryColor = typedValue.data;

mTextView.setTextColor(primaryColor);

Ответ 1

Наконец, я использовал следующий код, чтобы получить основной цвет текста темы -

// Get the primary text color of the theme
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getActivity().getTheme();
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
TypedArray arr =
        getActivity().obtainStyledAttributes(typedValue.data, new int[]{
                android.R.attr.textColorPrimary});
int primaryColor = arr.getColor(0, -1);

Ответ 2

Вам необходимо проверить, разрешен ли атрибут для ресурса или значения цвета.

Значением по умолчанию textColorPrimary является не Color, а ColorStateList, который является ресурсом.

@ColorInt public static int resolveColorAttr(Context context, @AttrRes int colorAttr) {
  TypedValue resolvedAttr = resolveThemeAttr(context, colorAttr);
  // resourceId is used if it a ColorStateList, and data if it a color reference or a hex color
  int colorRes = resolvedAttr.resourceId != 0 ? resolvedAttr.resourceId : resolvedAttr.data;
  return ContextCompat.getColor(context, colorRes);
}

public static TypedValue resolveThemeAttr(Context context, @AttrRes int attrRes) {
  Theme theme = context.getTheme();
  TypedValue typedValue = new TypedValue();
  theme.resolveAttribute(attrRes, typedValue, true);
  return typedValue;
}

Использование:

@ColorInt int color = resolveColorAttr(context, android.R.attr.textColorPrimaryInverse);

Ответ 3

Версия расширения в котлине

@ColorInt
fun Context.getColorResCompat(@AttrRes id: Int): Int {
    val resolvedAttr = TypedValue()
    this.theme.resolveAttribute(id, resolvedAttr, true)
    val colorRes = resolvedAttr.run { if (resourceId != 0) resourceId else data }
    return ContextCompat.getColor(this, colorRes)
}

использование:

textView.setTextColor(mActivity.getColorResCompat(android.R.attr.textColorPrimary))

Ответ 4

Это kotlin версия ответа @benjiko99. Я только добавил это в случае, если кому-то это нужно. Работал нормально для меня. Спасибо @Benjiko99

fun resolveThemeAttr(context: Context, @AttrRes attrRes: Int): TypedValue {
    val theme = context.theme
    val typedValue = TypedValue()
    theme.resolveAttribute(attrRes, typedValue, true)
    return typedValue
}
@ColorInt
fun resolveColorAttr(context: Context, @AttrRes colorAttr: Int): Int {
    val resolvedAttr = resolveThemeAttr(context, colorAttr)
    // resourceId is used if it a ColorStateList, and data if it a color reference or a hex color
    val colorRes = if (resolvedAttr.resourceId != 0)
            resolvedAttr.resourceId
        else
            resolvedAttr.data
    return ContextCompat.getColor(context, colorRes)
}

Использование:

@ColorInt val color = resolveColorAttr(view.context,
    android.R.attr.textColorPrimary)