androidmaterial-components-androidandroid-togglebutton

How to make customized Material Toggle Button?


I want to customized Material Toggle Button like the following. I have tried but not succeed to achieve this output. following is xml code I tried but not desired output. I go through the Offical Documents but no help about this. Please help me if anyone knows about this Thanks

Desired Output

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

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

output

enter image description here


Solution

  • This can be achieved using a TabLayout inside a MaterialCardView. The MaterialCardView is needed to draw the corner radius of the outer section and the TabLayout to draw each Tab. The TabLayout has a property app:tabBackground which can be used to set a Drawable selector for the Tab Selected/Unselected state.

    Xml layout:

    <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>
    

    where @drawable/tabs_selector is the Tab Drawable Selector to set the Selected/Unselected state like below:

    <?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>
    

    For @drawable/tab_bg_selected Selected state:

    <?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>
    

    For @drawable/tab_bg_unselected Unselected State:

    <?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>
    

    and @style/CustomTabTextAppearance is a custom Tab TextAppearance in case you want to change for each Tab the Text Size or Font Family like below:

    <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>
    

    Result:

    Tab1_Selected

    Tab2_Selected

    Tab3_Selected