找不到 attr 时如何使自定义视图回退到主题?
How to make a custom view fall back to a theme when attr is not found?
所以我制作了一个自定义视图,可以使用属性对其进行自定义,这很好用。
不过,我现在在为其实施主题系统时遇到了麻烦。我怎样才能取回它?
这就是我初始化 class 的方式:
class PairingCard @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr)
这是我检索的属性:
context.theme.obtainStyledAttributes(
attrs,
R.styleable.pairingCard,
defStyleAttr, R.style.Widget_ScitalysComponents_PairingCard
).apply {
try {
_strokeColor = getColor(
R.styleable.pairingCard_strokeColor,
ColorUtils.setAlphaComponent(
context.getColorFromAttr(R.attr.colorOnSurface),
196
)
)
正如您现在看到的,当它没有找到 attr 设置时,它会回退到具有 196 alpha 的颜色表面。我怎样才能让它恢复到 R.style.Widget_ScitalysComponents_PairingCard 中定义的颜色?
我考虑过再做一次 getColor,但老实说感觉不对。
这是attrs.xml:
<declare-styleable name="pairingCard">
<attr name="strokeColor" format="color|reference"/>
<attr name="strokeWidth" format="dimension"/>
<attr name="cardElevation" format="dimension"/>
<attr name="collapsedBackgroundColor" format="color"/>
<attr name="expandedBackgroundColor" format="color"/>
<attr name="chevronTint" format="color"/>
</declare-styleable>
这是styles.xml:
<style name="Widget.ScitalysComponents.PairingCard" parent="Widget.MaterialComponents.CardView">
<item name="strokeColor">?attr/colorOnSurface</item>
<item name="strokeWidth">1dp</item>
<item name="cardElevation">@dimen/cardview_default_elevation</item>
<item name="collapsedBackgroundColor">?attr/colorOnSurface</item>
<item name="expandedBackgroundColor">?attr/colorOnSurface</item>
<item name="chevronTint">?attr/colorPrimary</item>
</style>
谢谢大家!
在您的 attires.xml 中,您应该定义一个主题引用属性
<declare-styleable name="AppTheme">
<attr name = "pairingCardStyle" format = "reference"/>
</declare-styleable>
那么你应该在你的样式中定义属性
<style name="Widget.AppTheme.pairingCard" parent="">
<item name="strokeColor">?attr/colorOnSurface</item>
.....
</style>
之后,您必须将此样式指向主题中的引用。
<style name="Theme.App" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name = "pairingCardStyle">@style/Widget.AppTheme.pairingCard</item>
......
</style>
在您的自定义视图 class 中,您需要定义这些属性
context.theme.obtainStyledAttributes(
attrs,
R.styleable.pairingCard,
R.attr.pairingCardStyle,
R.style.Widget_AppTheme_pairingCard
)
所以我制作了一个自定义视图,可以使用属性对其进行自定义,这很好用。 不过,我现在在为其实施主题系统时遇到了麻烦。我怎样才能取回它?
这就是我初始化 class 的方式:
class PairingCard @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr)
这是我检索的属性:
context.theme.obtainStyledAttributes(
attrs,
R.styleable.pairingCard,
defStyleAttr, R.style.Widget_ScitalysComponents_PairingCard
).apply {
try {
_strokeColor = getColor(
R.styleable.pairingCard_strokeColor,
ColorUtils.setAlphaComponent(
context.getColorFromAttr(R.attr.colorOnSurface),
196
)
)
正如您现在看到的,当它没有找到 attr 设置时,它会回退到具有 196 alpha 的颜色表面。我怎样才能让它恢复到 R.style.Widget_ScitalysComponents_PairingCard 中定义的颜色?
我考虑过再做一次 getColor,但老实说感觉不对。
这是attrs.xml:
<declare-styleable name="pairingCard">
<attr name="strokeColor" format="color|reference"/>
<attr name="strokeWidth" format="dimension"/>
<attr name="cardElevation" format="dimension"/>
<attr name="collapsedBackgroundColor" format="color"/>
<attr name="expandedBackgroundColor" format="color"/>
<attr name="chevronTint" format="color"/>
</declare-styleable>
这是styles.xml:
<style name="Widget.ScitalysComponents.PairingCard" parent="Widget.MaterialComponents.CardView">
<item name="strokeColor">?attr/colorOnSurface</item>
<item name="strokeWidth">1dp</item>
<item name="cardElevation">@dimen/cardview_default_elevation</item>
<item name="collapsedBackgroundColor">?attr/colorOnSurface</item>
<item name="expandedBackgroundColor">?attr/colorOnSurface</item>
<item name="chevronTint">?attr/colorPrimary</item>
</style>
谢谢大家!
在您的 attires.xml 中,您应该定义一个主题引用属性
<declare-styleable name="AppTheme">
<attr name = "pairingCardStyle" format = "reference"/>
</declare-styleable>
那么你应该在你的样式中定义属性
<style name="Widget.AppTheme.pairingCard" parent="">
<item name="strokeColor">?attr/colorOnSurface</item>
.....
</style>
之后,您必须将此样式指向主题中的引用。
<style name="Theme.App" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name = "pairingCardStyle">@style/Widget.AppTheme.pairingCard</item>
......
</style>
在您的自定义视图 class 中,您需要定义这些属性
context.theme.obtainStyledAttributes(
attrs,
R.styleable.pairingCard,
R.attr.pairingCardStyle,
R.style.Widget_AppTheme_pairingCard
)