如何制作自定义 Material 切换按钮?

How to make customized Material Toggle Button?

我想自定义 Material 切换按钮,如下所示。我已经尝试但没有成功实现此输出。以下是 xml 代码我试过但不是想要的输出。我经历了 Offical Documents 但对此没有帮助。如果有人知道这件事,请帮助我 谢谢

xml

<com.google.android.material.button.MaterialButtonToggleGroup
                    android:id="@+id/outdoor_toggle_buttonGroup"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:singleSelection="true"
                    app:checkedButton="@+id/btn_walking"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:layout_marginBottom="@dimen/_20sdp"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    >

                    <Button
                        android:id="@+id/btn_walking"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/walking"
                        android:textColor="@color/white"
                        android:textAllCaps="false"
                        android:backgroundTint="@color/green"
                        style="@style/Widget.MaterialComponents.Button"
                        app:shapeAppearance="@style/CustomShapeAppearance"
                        />

                    <Button
                        android:id="@+id/btn_running"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/running"
                        android:textColor="@color/black"
                        android:textAllCaps="false"
                        android:backgroundTint="@color/white"
                        style="@style/Widget.MaterialComponents.Button"
                        app:shapeAppearance="@style/CustomShapeAppearance"
                        />

                    <Button
                        android:id="@+id/btn_cycling"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/cycling"
                        android:textColor="@color/black"
                        android:textAllCaps="false"
                        android:backgroundTint="@color/white"
                        style="@style/Widget.MaterialComponents.Button"
                        app:shapeAppearance="@style/CustomShapeAppearance"
                        />


                </com.google.android.material.button.MaterialButtonToggleGroup>

风格

 <style name="CustomShapeAppearance">
        <item name="cornerSizeTopLeft">20dp</item>
        <item name="cornerSizeTopRight">20dp</item>
        <item name="cornerSizeBottomLeft">20dp</item>
        <item name="cornerSizeBottomRight">20dp</item>
    </style>

输出

这可以通过在 MaterialCardView 中使用 TabLayout 来实现。需要 MaterialCardView 来绘制外部部分的角半径,需要 TabLayout 来绘制每个选项卡。 TabLayout 有一个 属性 app:tabBackground 可用于为 Tab Selected/Unselected 状态设置 Drawable 选择器。

Xml布局:

<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:strokeWidth="0dp"
    app:strokeColor="@android:color/transparent"
    app:cardCornerRadius="20dp">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:backgroundTint="@android:color/white"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:tabIndicatorColor="@android:color/transparent"
        app:tabIndicatorHeight="0dp"
        app:tabRippleColor="@android:color/transparent"
        app:tabTextColor="@android:color/black"
        app:tabSelectedTextColor="@android:color/white"
        app:tabBackground="@drawable/tabs_selector"
        app:tabTextAppearance="@style/CustomTabTextAppearance">

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Walking" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Running" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cycling" />

    </com.google.android.material.tabs.TabLayout>

</com.google.android.material.card.MaterialCardView>

其中 @drawable/tabs_selector 是用于设置 Selected/Unselected 状态的 Tab Drawable 选择器,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="true"
        android:drawable="@drawable/tab_bg_selected" />
    <item
        android:drawable="@drawable/tab_bg_unselected" />
</selector>

对于@drawable/tab_bg_selected选中状态:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#31d480" />
    <corners android:radius="20dp" />
</shape>

对于@drawable/tab_bg_unselected未选中状态:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/transparent" />
</shape>

@style/CustomTabTextAppearance 是自定义选项卡 TextAppearance,以防您想为每个选项卡更改文本大小或字体系列,如下所示:

<style name="CustomTabTextAppearance" parent="TextAppearance.MaterialComponents.Button">
    <item name="fontFamily">@font/roboto_mono</item>
    <item name="android:fontFamily">@font/roboto_mono</item>
    <item name="android:textAllCaps">false</item>
    <item name="android:textSize">14sp</item>
</style>

结果: