如何在MaterialButtonToggleGroup中实现图标与文本切换显示?
问题描述
现有一个横向布局的MaterialButtonToggleGroup,包含4个MaterialButton。部分设备的屏幕无法在一行显示所有按钮,因此希望未选中按钮仅显示图标,选中按钮显示图标+文本,能否通过样式实现?最好带有动画效果。
当前效果

目标效果


当前布局代码
<com.google.android.material.button.MaterialButtonToggleGroup android:id="@+id/rename_toggle_group" style="@style/CustomButtonToggleGroup" android:orientation="horizontal" android:layout_marginTop="@dimen/view_indent_vertical_min" android:gravity="center" app:checkedButton="@id/rename_current" app:selectionRequired="true" app:singleSelection="true"> <com.google.android.material.button.MaterialButton android:id="@+id/rename_current" android:minWidth="0dp" style="@style/MaterialButtonSecondaryToggle" app:icon="@drawable/ic_general" android:text="Current" /> <com.google.android.material.button.MaterialButton android:id="@+id/rename_top" android:minWidth="0dp" app:icon="@drawable/ic_general" style="@style/MaterialButtonSecondaryToggle" /> <com.google.android.material.button.MaterialButton android:id="@+id/rename_bottom" android:minWidth="0dp" style="@style/MaterialButtonSecondaryToggle" app:icon="@drawable/ic_general"/> <com.google.android.material.button.MaterialButton android:id="@+id/rename_all" android:minWidth="0dp" style="@style/MaterialButtonSecondaryToggle" app:icon="@drawable/ic_general" /> </com.google.android.material.button.MaterialButtonToggleGroup>
解决方案
可以通过自定义样式+状态选择器+属性动画实现需求,步骤如下:
1. 补全所有按钮的文本
给每个MaterialButton都添加android:text属性,后续通过状态控制文本显示/隐藏:
<com.google.android.material.button.MaterialButton android:id="@+id/rename_top" android:minWidth="0dp" app:icon="@drawable/ic_general" style="@style/MaterialButtonSecondaryToggle" android:text="Top" /> <com.google.android.material.button.MaterialButton android:id="@+id/rename_bottom" android:minWidth="0dp" style="@style/MaterialButtonSecondaryToggle" app:icon="@drawable/ic_general" android:text="Bottom"/> <com.google.android.material.button.MaterialButton android:id="@+id/rename_all" android:minWidth="0dp" style="@style/MaterialButtonSecondaryToggle" app:icon="@drawable/ic_general" android:text="All" />
2. 创建文本显示状态选择器
在res/drawable下新建btn_text_visibility.xml,用状态选择器控制文本透明度:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态:文本完全显示 --> <item android:state_checked="true"> <alpha android:alpha="1.0" /> </item> <!-- 未选中状态:文本完全隐藏 --> <item> <alpha android:alpha="0.0" /> </item> </selector>
3. 自定义按钮样式,绑定状态与动画
修改styles.xml中的MaterialButtonSecondaryToggle样式,添加状态绑定和动画配置:
<style name="MaterialButtonSecondaryToggle" parent="Widget.MaterialComponents.Button.OutlinedButton.Toggle"> <!-- 保留原有基础配置 --> <item name="android:minWidth">0dp</item> <!-- 绑定文本透明度的状态选择器 --> <item name="android:textColor">@drawable/btn_text_visibility</item> <!-- 开启布局变化动画,实现文本淡入淡出 --> <item name="android:animateLayoutChanges">true</item> <!-- 按钮宽度随内容自适应 --> <item name="android:width">wrap_content</item> <!-- 调整图标与文本的间距 --> <item name="iconPadding">4dp</item> </style>
如果需要更流畅的宽度变化动画,可添加属性动画:
在res/animator下新建btn_width_animator.xml:
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="width" android:duration="300" android:valueType="intType" android:interpolator="@android:interpolator/decelerate_cubic" />
然后在代码中给ToggleGroup添加选中监听,触发宽度动画:
rename_toggle_group.addOnButtonCheckedListener { group, checkedId, isChecked -> val targetButton = group.findViewById<MaterialButton>(checkedId) ?: return@addOnButtonCheckedListener if (isChecked) { // 选中时展开按钮宽度到适配文本的尺寸 targetButton.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) val animator = AnimatorInflater.loadAnimator(context, R.animator.btn_width_animator) animator.setTarget(targetButton) animator.setIntValues(targetButton.width, targetButton.measuredWidth) animator.start() } else { // 取消选中时收缩按钮到仅图标宽度 val iconTotalWidth = targetButton.icon.intrinsicWidth + targetButton.paddingStart + targetButton.paddingEnd val animator = AnimatorInflater.loadAnimator(context, R.animator.btn_width_animator) animator.setTarget(targetButton) animator.setIntValues(targetButton.width, iconTotalWidth) animator.start() } }
4. 小屏幕适配优化
给ToggleGroup添加横向滚动属性,避免小屏幕下按钮换行:
<com.google.android.material.button.MaterialButtonToggleGroup ... android:scrollHorizontally="true" android:clipToPadding="false"/>
设置完成后,未选中按钮仅显示图标,选中按钮会平滑展开显示图标+文本,完美适配小屏幕布局。
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

