单击时更改复选框背景?
Posted
技术标签:
【中文标题】单击时更改复选框背景?【英文标题】:Change Checkbox background on click? 【发布时间】:2021-11-27 12:18:49 【问题描述】:我有一个 Checkbox
,在 selector
中包含自定义图像...
我试图在点击checkbox
时达到以下效果:
Gif 供参考:
当按下 checkbox
时背景必须改变,然后在释放时恢复正常。
前两个按钮是ImageButtons
,效果很容易实现,但是Checkbox
我很挣扎。
我想它必须与selector
本身有关,但我不太确定如何实现它。我尝试在item
和solid
颜色中添加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
属性。这样你就不会失去阴影和涟漪效果。但也许您不希望它看起来像那样,在这种情况下,请忽略这一段。
【讨论】:
无法正常工作。我收到以下错误:找不到接受参数类型“布尔”的isChecked()
函数,就像 CheckBox 一样。以上是关于单击时更改复选框背景?的主要内容,如果未能解决你的问题,请参考以下文章