You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中使用TextView自定义样式时属性解析错误的解决方法

问题解决:Android弹窗加载布局时自定义属性解析失败

问题背景

自定义主题MyAppTheme中定义了一系列自定义属性,其中planesTextColor被用于CustomTextViewStyle的文本颜色配置:

<style name="MyAppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <!-- 系统主题属性省略 -->
    <item name="planesTextColor">@color/colorAmber700</item>
    <!-- 其他自定义属性省略 -->
</style>

<style name="CustomTextViewStyle" parent="@style/Widget.AppCompat.TextView">
    <item name="android:textColor">?planesTextColor</item>
</style>

弹窗布局help_popup.xml中使用了该自定义样式:

<TextView
     android:id="@+id/popup_help_title"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_margin="10dip"
     android:textSize="20dp"
     android:textStyle="bold"
     style="@style/CustomTextViewStyle"
     android:text="@string/help"/>

弹窗通过applicationContext加载布局:

val inflater = m_Context.getSystemService(AppCompatActivity.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val popupView = inflater.inflate(R.layout.help_popup, null)

此时抛出错误:

Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 5: TypedValue{t=0x2/d=0x7f040323 a=6}
    at android.content.res.TypedArray.getColorStateList(TypedArray.java:596)
    at android.widget.TextView.readTextAppearance(TextView.java:3961)

但在Fragment中使用相同样式却正常工作,Fragment布局加载方式为:

binding = FragmentLoginBinding.inflate(inflater, container, false)

问题原因

applicationContext使用的是应用默认主题,而非你自定义的MyAppTheme,而planesTextColor这类自定义属性仅在MyAppTheme中定义,因此LayoutInflater解析布局时无法找到属性定义,导致报错。

Fragment能正常工作是因为它的LayoutInflater继承了所在Activity的主题,而Activity已应用MyAppTheme。

解决方案

方案1:改用Activity上下文

将弹窗初始化时传入的上下文改为当前Activity实例,而非applicationContext:

val helpPopup = HelpPopup(this@YourActivity, m_MainLayout, mSelectedItem, ::startTutorialFragment)

这样LayoutInflater会自动使用Activity的自定义主题,正确解析自定义属性。

方案2:手动为LayoutInflater设置自定义主题

如果必须使用applicationContext,可以克隆LayoutInflater并绑定自定义主题:

val inflater = LayoutInflater.from(m_Context).cloneInContext(ContextThemeWrapper(m_Context, R.style.MyAppTheme))
val popupView = inflater.inflate(R.layout.help_popup, null)

方案3:直接引用颜色资源(不推荐)

若不需要主题切换能力,可修改CustomTextViewStyle直接使用颜色资源:

<style name="CustomTextViewStyle" parent="@style/Widget.AppCompat.TextView">
    <item name="android:textColor">@color/colorAmber700</item>
</style>

此方法会丧失主题切换灵活性,仅适合固定配色场景。

内容的提问来源于stack exchange,提问作者Cristi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:16:06