单击更改复选框背景?

Change Checkbox background on click?

我有一个 Checkbox,里面有自定义图像 selector...

我试图在单击 checkbox 时实现以下效果:

参考动图:

按下 checkbox 时背景必须改变,然后在松开时恢复正常。

前两个按钮是 ImageButtons 并且效果很容易实现,但是 Checkbox 我很挣扎。 我想它必须与 selector 本身有关,但我不太确定如何实现它。我尝试在 itemsolid 颜色中添加 shape,但我无法使其工作。请给我指明正确的方向。

我的复选框代码如下 (它使用双向数据绑定):

 <CheckBox
    android:id="@+id/btn_addtofavs"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/inflated_selector_is_checked"
    android:button="@null"
    android:checked="@={inflatedItemViewModel.item.checked}"
    android:onClick="@{() -> inflatedItemViewModel.updateChecked(inflatedItemViewModel.item.id, inflatedItemViewModel.item.checked)}"
    tools:ignore="ContentDescription" />

我的 Checkbox 选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@drawable/ic_inflated_star_outline"
        android:state_checked="false"/>

    <item
        android:drawable="@drawable/ic_inflated_star_full"
        android:state_checked="true"/>

    <item
        android:drawable="@drawable/ic_inflated_star_outline"/>

</selector>

其他 2 个按钮选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <solid android:color="@color/blue_200"/>
            <corners android:radius="@dimen/_8sdp"/>
        </shape>
    </item>

    <item android:state_pressed="false">
        <shape>
            <solid android:color="@color/blue_500"/>
            <corners android:radius="@dimen/_8sdp"/>
        </shape>
    </item>
</selector>

更新 1:由 Tenfour04 建议

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_addtofavs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@drawable/bg_button"
android:checkable="true"
android:checked="@={inflatedItemViewModel.item.checked}"
android:onClick="@{() -> inflatedItemViewModel.updateChecked(inflatedItemViewModel.item.id, inflatedItemViewModel.item.checked)}"
app:icon="@drawable/inflated_selector_is_checked"
app:iconGravity="textStart"
app:iconPadding="0dp"
tools:ignore="ContentDescription" />

出现错误:

Cannot find a getter for <com.google.android.material.button.MaterialButton android:checked> that accepts parameter type 'boolean' 

即编译器无法将其识别为两级按钮。我错过了什么吗?

我不使用数据绑定,所以不确定这是否适合您。但是...

如果您使用 Material Components 主题,Button 会在运行时自动转换为 MaterialButton。 MaterialButton 比常规 Button 更通用,包括内置的双态按钮和 ImageButton 的功能。这意味着它支持双态行为并具有 android:checked 属性。只需确保您设置的具有两个状态的状态 android:checkable="true".

使用 Button 而不是 CheckBox 的原因是,它可以很容易地使其样式看起来像您的其他按钮,因为您可以对所有按钮使用完全相同的样式。很难让 CheckBox 的文本、图标位置和填充看起来像其他的一样。

要使它的样式与所有三个按钮的样式相同,您可以使用 MaterialButton 的 app:icon 设置图标。设置 app:iconPadding="0dp"app:iconGravity="textStart" 以便在没有文本时它将在按钮中居中。

我不知道你现在是怎么做的,但我建议你不要为背景制作一个可绘制的选择器,而是制作一个 color selector (color state list),并将其设置为 app:backgroundTint 属性 个按钮。这样你就不会失去阴影和波纹效果。但也许你不希望它看起来像那样,在这种情况下,请忽略这一段。

好的,经过几个小时的研究,我想出了一个可行的解决方案。它有点长,所以请耐心等待。 以下是步骤:

1.定义星星在按下和释放时的样子:

我们将使用图层列表。

star_full.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">    
    <item>
        <shape>
            <solid android:color="@color/blue_500" />
            <corners android:radius="@dimen/_8sdp" />
            <padding
                android:bottom="@dimen/_12sdp"
                android:left="@dimen/_12sdp"
                android:right="@dimen/_12sdp"
                android:top="@dimen/_12sdp" />
        </shape>
    </item>

    <item android:drawable="@drawable/ic_inflated_star_full" />
</layer-list>

star_full_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="@color/blue_200" />
            <corners android:radius="@dimen/_8sdp" />
            <padding
                android:bottom="@dimen/_12sdp"
                android:left="@dimen/_12sdp"
                android:right="@dimen/_12sdp"
                android:top="@dimen/_12sdp" />
        </shape>
    </item>

    <item android:drawable="@drawable/ic_inflated_star_full" />
</layer-list>

star_outline.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">    
    <item>
        <shape>
            <solid android:color="@color/blue_500" />
            <corners android:radius="@dimen/_8sdp" />
            <padding
                android:bottom="@dimen/_12sdp"
                android:left="@dimen/_12sdp"
                android:right="@dimen/_12sdp"
                android:top="@dimen/_12sdp" />
        </shape>
    </item>

    <item android:drawable="@drawable/ic_inflated_star_outline" />
</layer-list>

star_outline_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="@color/blue_200" />
            <corners android:radius="@dimen/_8sdp" />
            <padding
                android:bottom="@dimen/_12sdp"
                android:left="@dimen/_12sdp"
                android:right="@dimen/_12sdp"
                android:top="@dimen/_12sdp" />
        </shape>
    </item>

    <item android:drawable="@drawable/ic_inflated_star_outline" />
</layer-list>

2。创建两个选择器 - 一个用于 star_full,一个用于 star_outline.

我们将把我们的层列表分配给这两个选择器,它们将为两个图标中的每一个在 state_pressed="true"state_pressed="false" 之间切换。

selector_star_full_is_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/star_full_pressed" android:state_pressed="true" />

    <item android:drawable="@drawable/star_full" android:state_pressed="false" />
</selector>

selector_star_outline_is_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/star_outline_pressed" android:state_pressed="true" />

    <item android:drawable="@drawable/star_outline" android:state_pressed="false" />
</selector>

3。将这两个选择器分配给我们的复选框选择器。

复选框选择器将在 android:state_checked="true"android:state_checked="false" 之间切换。

selector_checkbox_is_checked.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/selector_star_outline_is_pressed.xml" android:state_checked="false" />

    <item android:drawable="@drawable/selector_star_full_is_pressed.xml" android:state_checked="true" />

    <item android:drawable="@drawable/selector_star_outline_is_pressed.xml" />

</selector>

最终结果应该是这样的: