首页 > 解决方案 > 找不到 attr 时如何使自定义视图回退到主题?

问题描述

所以我制作了一个自定义视图,可以使用属性进行自定义,这很好并且可以工作。不过,我现在无法为其实施主题系统。我怎样才能找回它?

这就是我初始化类的方式:

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

正如您现在看到的,当它没有找到属性设置时,它会退回到具有 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>

谢谢大家!

标签: androidkotlinandroid-custom-viewandroid-styles

解决方案


在你的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>

在自定义视图的类中,您需要定义这些属性

context.theme.obtainStyledAttributes(
        attrs,
        R.styleable.pairingCard,
        R.attr.pairingCardStyle,
        R.style.Widget_AppTheme_pairingCard
    )

推荐阅读