单击时更改复选框背景?

Posted

技术标签:

【中文标题】单击时更改复选框背景?【英文标题】:Change Checkbox background on click? 【发布时间】:2021-11-27 12:18:49 【问题描述】:

我有一个 Checkbox,在 selector 中包含自定义图像...

我试图在点击checkbox时达到以下效果:

Gif 供参考:

当按下 checkbox 时背景必须改变,然后在释放时恢复正常。

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

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

 <CheckBox
    android:id="@+id/btn_addtofavs"
    android:layout_
    android:layout_
    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_
android:layout_
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' 

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

【问题讨论】:

为什么不使用普通的 imageview 而不是 checkbox 。维护一个标志并点击切换标志和带有选中图像的图像。 我猜是因为双向数据绑定 @pepper90,您是否尝试使用android:state_pressed="true" 向您的inflated_selector_is_checked 添加状态? @Demigod 请给我看我案例中的代码。 【参考方案1】:

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

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>

最终的结果应该是这样的:

【讨论】:

【参考方案2】:

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

如果您使用 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 属性。这样你就不会失去阴影和涟漪效果。但也许您不希望它看起来像那样,在这种情况下,请忽略这一段。

【讨论】:

无法正常工作。我收到以下错误:找不到接受参数类型“布尔”的 的吸气剂。我更新了我的帖子,请检查。 我之前没用过数据绑定。我刚试了一下,也遇到了同样的问题。我想不通。 MaterialButton 显然有一个isChecked() 函数,就像 CheckBox 一样。

以上是关于单击时更改复选框背景?的主要内容,如果未能解决你的问题,请参考以下文章

单击复选框时更改标签颜色

单击时更改复选框值

单击操作栏项目复选框时,更改其状态

激活复选框时更改其背景颜色[重复]

单击列表项更改复选框状态?

Excel VBA复选框单击和更改事件相同吗?