以编程方式将文本颜色设置为主要的 android textview

Posted

技术标签:

【中文标题】以编程方式将文本颜色设置为主要的 android textview【英文标题】:Programmatically set text color to primary android textview 【发布时间】:2016-01-08 03:41:43 【问题描述】:

如何以编程方式将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) 主题调试器来编辑您的主题。我知道这不是直接的答案,但它可能是一个很好的解决方法。 我不打算在任何地方使用setTextColor。我想为特定的TextView 设置从次要到主要的颜色。 你能不能把它当作... .. mTextView.setTextColor(android.R.attr.textColorPrimary); @sourabhbans 不,这不起作用:( 您是否在为应用使用自定义主题? 【参考方案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);

【讨论】:

别忘了在你最后一行arr.recycle()之后回收TypedArray。 它可以工作,但会导致“无效 ID”错误。 Benjiko99 的回答不会导致这个错误。【参考方案2】:

您需要检查属性是否已解析为资源颜色值

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

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)

【讨论】:

最佳答案 imo。 jaibatrik 的回答也有效,但它导致了“无效 ID”错误。【参考方案3】:

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

【讨论】:

【参考方案4】:

这是我的解决方案:

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

getResIdFromAttribute

    @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
    

【讨论】:

【参考方案5】:

这是another回复的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)

【讨论】:

以上是关于以编程方式将文本颜色设置为主要的 android textview的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 11 (API 30) 中以编程方式更改状态栏文本颜色

Android:以编程方式更改选项卡文本颜色

以编程方式为 NativeScript Vue 中的标签设置“跨度”颜色在 FormattedString 中不起作用

以编程方式在android中将下划线文本设置为TextView

以编程方式设置 UIButton 文本颜色 [重复]

以编程方式更改UIButton的标题颜色,其标题设置为iOS 7中的属性