以编程方式将文本颜色设置为Android主要TextView

31

我该如何以编程方式将我的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);

通常我会扩展TextView类并在应用程序的各个地方使用它。在我的TextView类中,我设置默认颜色、字体等等。另一种方法是创建一个带有所需颜色的静态变量,并在任何地方使用.setTextColor();。第三种方法是使用新的Android Studio(1.4)主题调试器来编辑您的主题。我知道这不是直接的答案,但它可能是一个不错的解决方法。 - Kamen Stoykov
我不打算在所有地方使用 setTextColor。我想为特定的 TextView 将颜色从次要设置为主要。 - jaibatrik
1
你可以尝试使用以下代码... mTextView.setTextColor(android.R.attr.textColorPrimary); - SRB Bans
1
@sourabhbans 不,那不起作用 :( - jaibatrik
你是否在使用自定义主题来开发应用程序? - SRB Bans
5个回答

38

最终,我使用以下代码获取主题的主要文本颜色 -

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

14
在你的最后一行代码 arr.recycle() 之后,不要忘记对 TypedArray 进行回收。 - sorianiv
它可以运行,但引起了“无效的 ID”错误。Benjiko99的答案不会引起此错误。 - user10981072

26

你需要检查属性是否被解析为一个资源或一个颜色值

textColorPrimary的默认值不是一个Color,而是一个ColorStateList,它是一个资源

Kotlin 解决方案

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

fun Context.resolveThemeAttr(@AttrRes attrRes: Int): TypedValue {
    val typedValue = TypedValue()
    theme.resolveAttribute(attrRes, typedValue, true)
    return typedValue
}

使用方法

@ColorInt val color = context.resolveColorAttr(android.R.attr.textColorPrimaryInverse)

我认为这是最佳答案。jaibatrik的回答也可以,但会导致“无效ID”错误。 - user10981072

8

Kotlin 中的扩展版本

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

1

Here's my solution for it:

@ColorInt
fun Context.getColorCompat(@ColorRes colorRes: Int) =  ContextCompat.getColor(this, colorRes)
@ColorInt
fun Fragment.getColorCompat(@ColorRes colorRes: Int) = activity!!.getColorCompat(colorRes)

@ColorInt
fun Activity.getColorCompatFromAttr(@AttrRes colorAttrRes: Int) = getColorCompat(getResIdFromAttribute(this, colorAttrRes))
@ColorInt
fun Fragment.getColorCompatFromAttr(@AttrRes colorAttrRes: Int) = activity!!.getColorCompatFromAttr(colorAttrRes)

获取属性中的资源ID
    @JvmStatic
    fun getResIdFromAttribute(activity: Activity, @AttrRes attr: Int): Int {
        if (attr == 0)
            return 0
        val typedValue = TypedValue()
        activity.theme.resolveAttribute(attr, typedValue, true)
        val resourceId = typedValue.resourceId
        return if (resourceId != 0)
            resourceId
        else typedValue.data
    }

1
这是另一个回复的Kotlin版本。我只是为了方便需要它的人而添加了它。对我来说运行良好。
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's a ColorStateList, and data if it's 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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接