Android中点击Button如何切换绑定的Drawable图标?
问题描述
在CardLayout中有一个「save」按钮,用户点击后将内容保存至另一个Fragment,同时需要切换按钮的「heart」Drawable图标和文本。目前已实现文本切换,但不清楚如何切换图标。
现有代码
Kotlin点击事件代码
binding.saves.setOnClickListener { val exist = dbHandler.getTask(task.id) if(exist) { Toast.makeText(itemView.context, "Activity removed", Toast.LENGTH_SHORT) .show() binding.saves.text ="Save" dbHandler.deleteFavorite(task); }else{ Toast.makeText(itemView.context, "Activity added", Toast.LENGTH_SHORT) .show() dbHandler.addFavorite(task); binding.saves.text ="Saved" } }
XML布局代码
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="0dp" app:cardBackgroundColor="@color/white" app:cardCornerRadius="0dp" app:cardElevation="0dp" app:cardMaxElevation="3dp" app:cardPreventCornerOverlap="true" app:cardUseCompatPadding="true" tools:context="ui.CardLayout"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/idActivityName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="14dp" android:layout_marginRight="10dp" android:text="@string/placeholdertasktitle" android:textColor="@color/black" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/idActivityDescription" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/idActivityName" android:layout_marginStart="10dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:layout_marginEnd="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="30dp" android:drawablePadding="2dp" android:text="@string/activitydescription" android:textColor="@color/black" android:textSize="15sp" tools:ignore="UnknownId" /> <View android:id="@+id/divider" android:layout_width="380dp" android:layout_height="2dp" android:layout_below="@id/idActivityDescription" android:layout_alignStart="@id/idActivityName" android:background="#EDEDED" /> <LinearLayout android:id="@+id/linLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/divider" android:layout_alignStart="@+id/divider" android:layout_alignEnd="@+id/divider" android:gravity="center" android:orientation="horizontal"> <Button android:id="@+id/saves" style="@style/cardbutton" android:layout_width="110dp" android:layout_height="wrap_content" android:background="@drawable/cardbutton" android:contentDescription="@string/saves" android:stateListAnimator="@null" android:text="@string/save" android:textAlignment="center" android:textColor="#595959" android:textSize="12sp" app:icon="@drawable/ic_saves_blank" app:iconGravity="start" app:iconTint="#595959" /> <Button android:id="@+id/calendar" style="@style/cardbutton" android:layout_width="110dp" android:layout_height="wrap_content" android:background="@drawable/cardbutton" android:contentDescription="@string/saves" android:stateListAnimator="@null" android:text="@string/calendar" android:textAlignment="center" android:textColor="#595959" android:textSize="12sp" app:icon="@drawable/ic_calendar" app:iconTint="#595959" app:iconGravity="start"/> <Button android:id="@+id/copyactivity" style="@style/cardbutton" android:layout_width="110dp" android:layout_height="wrap_content" android:background="@drawable/cardbutton" android:contentDescription="@string/saves" android:stateListAnimator="@null" android:text="@string/copy" android:textAlignment="center" android:textColor="#595959" android:textSize="12sp" app:icon="@drawable/ic_copytext" app:iconGravity="start" app:iconTint="#595959" /> </LinearLayout> </RelativeLayout> </androidx.cardview.widget.CardView>
已尝试方法
- 尝试用
binding.saves.image ="drawable1"这类方式,但不清楚正确的切换方法 - 考虑将Button改为ImageButton并使用selected状态属性
需求疑问
是否需要将Button替换为ImageButton?能否通过Binding直接切换图标同时保留文本?
解决方案
不需要替换为ImageButton,你当前使用的是Material Button(从app:icon属性可判断),它本身支持图标与文本共存,直接通过Binding即可切换图标,有两种实现方式:
方式1:直接在代码中切换图标资源
在切换文本的同时,调用setIconResource()方法切换图标:
binding.saves.setOnClickListener { val exist = dbHandler.getTask(task.id) if(exist) { Toast.makeText(itemView.context, "Activity removed", Toast.LENGTH_SHORT).show() binding.saves.text = "Save" // 切换为空白心形图标 binding.saves.setIconResource(R.drawable.ic_saves_blank) dbHandler.deleteFavorite(task) }else{ Toast.makeText(itemView.context, "Activity added", Toast.LENGTH_SHORT).show() binding.saves.text = "Saved" // 切换为填充心形图标 binding.saves.setIconResource(R.drawable.ic_saves_filled) dbHandler.addFavorite(task) } }
如果需要同时切换图标颜色,可搭配iconTint:
// 示例:切换为红色填充图标 binding.saves.iconTint = ContextCompat.getColorStateList(itemView.context, R.color.red)
方式2:使用StateListDrawable自动切换(更简洁)
通过定义状态选择器Drawable,让系统根据按钮的selected状态自动切换图标,无需手动调用图标切换方法:
- 创建
drawable/ic_saves_selector.xml状态选择器:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态显示填充心形 --> <item android:drawable="@drawable/ic_saves_filled" android:state_selected="true"/> <!-- 默认状态显示空白心形 --> <item android:drawable="@drawable/ic_saves_blank"/> </selector>
- 修改XML中按钮的
app:icon属性:
<Button android:id="@+id/saves" ... app:icon="@drawable/ic_saves_selector" ... />
- 在代码中切换按钮的
selected状态即可联动图标与文本:
binding.saves.setOnClickListener { val exist = dbHandler.getTask(task.id) val isSelected = !exist binding.saves.isSelected = isSelected if(exist) { Toast.makeText(itemView.context, "Activity removed", Toast.LENGTH_SHORT).show() binding.saves.text = "Save" dbHandler.deleteFavorite(task) }else{ Toast.makeText(itemView.context, "Activity added", Toast.LENGTH_SHORT).show() binding.saves.text = "Saved" dbHandler.addFavorite(task) } }
内容的提问来源于stack exchange,提问作者user19437536
相关产品推荐
相关产品推荐

