为View设置?attr/colorControlNormal等属性时安卓7及以下App崩溃如何解决
崩溃原因
- 核心问题为Android 7.0(API 24)及更低版本系统不支持直接将主题颜色属性引用作为
android:background属性的取值。?attr/colorControlNormal、?attr/colorSurface、?attr/colorOnSurface这类属性本质指向颜色资源,而background属性默认接收drawable类型资源,高版本Android系统做了自动适配转换逻辑,低版本无对应兼容能力,因此会抛出资源未找到异常。
解决方案
方案1:改用backgroundTint属性搭配基础drawable(最简方案,无需额外适配日夜间主题)
给View设置一个无实际颜色影响的基础drawable,再通过backgroundTint引用主题颜色属性,低版本系统对backgroundTint的属性解析兼容更完善:
<View android:id="@+id/divider2" android:layout_width="match_parent" android:layout_height="1dp" android:background="@android:color/white" android:backgroundTint="?attr/colorControlNormal"/>
方案2:自定义分割线View,代码动态获取主题属性设置背景
如果需要更通用的全局兼容,可以在代码层解析主题属性值再设置背景:
- 自定义分割线类示例:
class ThemeDividerView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrs, defStyleAttr) { init { // 动态解析主题属性颜色值 val typedValue = TypedValue() context.theme.resolveAttribute(android.R.attr.colorControlNormal, typedValue, true) setBackgroundColor(typedValue.data) } }
- 布局中直接引用自定义View即可:
<com.yourpackage.name.ThemeDividerView android:layout_width="match_parent" android:layout_height="1dp"/>
方案3:封装shape drawable作为背景
将主题颜色引用写到shape资源的solid属性中,系统对drawable内部的主题属性引用兼容度更高:
- 创建
drawable/divider_theme_bg.xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="?attr/colorControlNormal" /> </shape>
- 布局中设置该drawable为背景:
<View android:id="@+id/divider2" android:layout_width="match_parent" android:layout_height="1dp" android:background="@drawable/divider_theme_bg"/>
内容的提问来源于stack exchange,提问作者Venkat
相关产品推荐
相关产品推荐

