通过自定义非布尔属性的布局选择器。可能吗?

时间:2018-07-20 16:55:46

标签: android view android-custom-view

我发现了很多关于如何为自定义布尔属性(例如How to add a custom button state)创建选择器的文章。但是我找不到如何为枚举或整数选择器。可能吗?

例如,我具有自定义的枚举属性

<declare-styleable name="status_indicator">
    <attr name="status" format="enum">
        <enum name="value_offline" value="0"/>
        <enum name="value_away" value="1"/>
        <enum name="value_online" value="2"/>
    </attr>
</declare-styleable>

我想使用带有选择器的背景

<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:drawable="@drawable/status_offline" app:status="value_offline"/>
    <item android:drawable="@drawable/status_away" app:status="value_away"/>
    <item android:drawable="@drawable/status_online" app:status="value_online"/>
    <item>
        <shape android:shape="oval">
            <solid android:color="#ff00ff"/>
        </shape>
    </item>
</selector>

此代码可以编译,但是选择器始终应用第一项,因为它没有条件。我阅读了源代码,发现通过属性集的比较来进行项目匹配。我认为android框架无法为带有枚举或整数的条件建立有效的属性集?

1 个答案:

答案 0 :(得分:0)

我发明了一种枚举的解决方法-声明虚假的布尔属性,例如status_online,status_away,status_offline,并根据实际的“状态”属性值以编程方式将其置于视图状态。但是它看起来很丑陋,无法解决不确定的整数问题(一定数量的整数也可以用伪布尔值属性代替)

解决方法的实现:

<declare-styleable name="status_indicator">
    <attr name="status_offline" format="boolean"/>
    <attr name="status_away" format="boolean"/>
    <attr name="status_online" format="boolean"/>
    <attr name="status" format="enum">
        <enum name="value_offline" value="0"/>
        <enum name="value_away" value="1"/>
        <enum name="value_online" value="2"/>
    </attr>
</declare-styleable>

@Override
public int[] onCreateDrawableState(int extraSpace) {
    final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
    switch (status) {
        case STATUS_ONLINE:
            mergeDrawableStates(drawableState, STATE_STATUS_ONLINE);
            break;
        case STATUS_AWAY:
            mergeDrawableStates(drawableState, STATE_STATUS_AWAY);
            break;
        case STATUS_OFFLINE:
            mergeDrawableStates(drawableState, STATE_STATUS_OFFLINE);
            break;
        default:
            break;
    }

    return drawableState;
}

然后选择器的布局应该看起来很生

<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:drawable="@drawable/status_offline" app:status_offline="true"/>
    <item android:drawable="@drawable/status_away" app:status_away="true"/>
    <item android:drawable="@drawable/status_online" app:status_online="true"/>
    <item>
        <shape android:shape="oval">
            <solid android:color="#ff00ff"/>
        </shape>
    </item>
</selector>