You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MaterialButtonToggleGroup中实现图标与文本切换显示?

问题描述

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

当前效果

当前效果示意图

目标效果

目标效果示意图1
目标效果示意图2

当前布局代码

<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:03:16