'Circular Progress Indicator inside Buttons, Android Material design

I have just read that buttons (MaterialButton) (progress indicator material design) in Material Design, are able to hold a circular progress Indicator, as you can see in the attached picture

enter image description here

Bassically when you press the button remove text and show a progress indicator, but there is no clue about how to implement it, does anybody already deal with it?

it will be really appreciate any hint. Thanks



Solution 1:[1]

One of the ways this can be achieved is to create a Layout where you'll have a container and place both the button and the CircularProgressIndicator

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/some_height"
        android:background="#00000000"
        android:layout_marginRight="@dimen/margin_right"
        android:layout_marginLeft="@dimen/margin_left">

        <Button
            android:id="@+id/btn_download"
            android:layout_width="match_parent"
            android:layout_height="@dimen/some_height"
            android:text="Download"
            android:layout_gravity="center"
            android:visibility="visible"
            android:textColor="#FFFFFF"/>

     
    <com.google.android.material.progressindicator.CircularProgressIndicator
            android:id="@+id/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </FrameLayout>

Then you would just toggle the visibility of the progress bar and remove the text.

Another way is to use custom animation drawable. You would then add this to your button as a drawableStart or drawableEnd with some positioning, or perhaps even as a background.

3rd option would be, as per: https://stackoverflow.com/a/65180647/13187710

BTW, in the xml code above, you can substitute Button with MaterialButton.

Solution 2:[2]

With the MaterialComponents library you can use the IndeterminateDrawable class to create a CircularProgressIndicator and apply it to a Button or the icon in a Button:

   val spec =
        CircularProgressIndicatorSpec(this,  /*attrs=*/null, 0,
            com.google.android.material.R.style.Widget_Material3_CircularProgressIndicator_ExtraSmall)
    val progressIndicatorDrawable =
        IndeterminateDrawable.createCircularDrawable(this, spec)
    //...
    button.setOnClickListener {
        button.icon = progressIndicatorDrawable
    }

With:

<com.google.android.material.button.MaterialButton
    android:id="@+id/indicator_button"
    style="@style/Widget.Material3.Button.OutlinedButton.Icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:text="Button"/>

enter image description here

With Compose you can use something like:

 var progressIndicatorVisible by remember { mutableStateOf(false) }

 Button(
   onClick = {
     scope.launch {
         progressIndicatorVisible = true

         // Just for example
         delay(5000)
         progressIndicatorVisible = false
     }
   }, 
   modifier = Modifier.animateContentSize()){

     if (progressIndicatorVisible) {
         CircularProgressIndicator(
             color = White,
             strokeWidth = 2.dp,
             modifier = Modifier.size(15.dp)
         )
     }
     Text (
         "Button",
         modifier = Modifier.padding(start = if (progressIndicatorVisible) 8.dp else 0.dp)
     )
 }

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gabriele Mariotti