FloatingActionButton en Android studio + Variantes | Jetpack Compose

Video thumbnail

 El Floating Action Button (FAB) o botón de acción flotante es un componente clave en el diseño de interfaces de usuario para aplicaciones Android. Se utiliza para representar la acción principal o más común en una pantalla. En esta entrada, exploraremos cómo implementar este botón tanto con el moderno Jetpack Compose como con el sistema de vistas tradicional (Legacy View System) basado en XML.

Quedamos en que aprendimos a usar los Botones en Android Studio: FilledTonalButton OutlinedButton TextButton Column Click Iconos

Floating Action Button con Jetpack Compose (El enfoque moderno)

Jetpack Compose es el conjunto de herramientas moderno y recomendado por Google para crear interfaces de usuario nativas en Android. Su naturaleza declarativa simplifica enormemente el desarrollo de UI.

¿Qué es un Floating Action Button?

Básicamente es un tipo de botón, pero un poco más “rico” que los anteriores.

Podemos cambiar el tamaño, agregar texto (en el caso del botón extendido) y, por supuesto, siempre tiene un icono. Como siempre, también tiene su evento onClick.

Tipos de botones flotantes

El uso de estos botones es muy sencillo; son más "ricos" visualmente que los botones estándar y permiten variar su tamaño o añadir texto:

  • SmallFloatingActionButton: Una versión pequeña.
  • LargeFloatingActionButton: Para destacar más la acción.
  • ExtendedFloatingActionButton: Permite incluir un icono y una etiqueta de texto.
  • FloatingActionButton: El tamaño por defecto.

Implementación del FAB en Compose

Al igual que antes, es solo un botón y veamos alguna variantes en el siguiente ejemplo:

import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.LargeFloatingActionButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallFloatingActionButton
***
@Composable
fun ExamplesFAB() {
    Column(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(20.dp)
    ) {
        // 1. FAB SMALL
        SmallFloatingActionButton(
            onClick = { },
            containerColor = MaterialTheme.colorScheme.secondaryContainer,
            contentColor = MaterialTheme.colorScheme.secondary
        ) {
            Icon(Icons.Filled.Add, "Small floating action button.")
        }

        // 2. FAB Large
        LargeFloatingActionButton(
            onClick = { },
//            shape = CutCornerShape(1.dp)
//            shape = RectangleShape
            shape = RoundedCornerShape(15.dp)
//            shape = CircleShape,
        ) {
            Icon(Icons.Filled.Add, "Large floating action button")
        }

        // 3. FAB + TEXT
        ExtendedFloatingActionButton(
            onClick = { },
            icon = { Icon(Icons.Filled.Add, "Extended floating action button.") },
            text = { Text(text = "Extended FAB") },
        )

        // 4. FAB
        FloatingActionButton(
            onClick = {  },
        ) {
            Icon(Icons.Filled.Add, "Floating action button.")
        }

    }
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MyProyectAndroidTheme {
       // Greeting("Andasasasroid")
        ExamplesButtons()
        //ExamplesFAB()
    }
}

Personalización con Shape

Algo interesante es la propiedad shape, que define la forma del botón.
Todos los botones comparten estas propiedades; algunas se las he colocado y otras no, solo para mostrar diferencias visuales.

Por ejemplo:

  • CutCornerShape: esquinas recortadas
  • RoundedCornerShape: esquinas redondeadas

Aquí es necesario importar la clase correspondiente y definir el tamaño, por ejemplo 12.dp.

El efecto es muy parecido a lo que en desarrollo web sería un border-radius.

Usarlo en las actividades junto con el Scaffold

En Compose, el FloatingActionButton se integra típicamente dentro de un Scaffold, que proporciona una estructura estándar de Material Design para tu pantalla.

@Composable
fun FabExampleScreen() {
    Scaffold(
        floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    // Acción al hacer clic en el FAB
                    println("FAB presionado!")
                }
            ) {
                Icon(
                    imageVector = Icons.Default.Add,
                    contentDescription = "Agregar"
                )
            }
        },
        floatingActionButtonPosition = FabPosition.End
    ) { innerPadding ->
        // Contenido de tu pantalla
        Box(
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("Contenido de la pantalla")
        }
    }
}

En este ejemplo:

  • Scaffold organiza la pantalla y nos da un espacio dedicado para el FAB (floatingActionButton).
  • FloatingActionButton es el composable que crea el botón. Su lambda onClick define la acción a ejecutar.
  • Icon se usa para mostrar un ícono dentro del FAB, usando los íconos predefinidos de Material (Icons.Default.Add).

Como puedes ver, el código es conciso, declarativo y mucho más intuitivo que el enfoque basado en XML.

Floating Action Button con XML (Enfoque Legacy)

Aunque Jetpack Compose es el futuro, muchas aplicaciones existentes todavía usan el sistema de vistas basado en XML. A continuación, se detalla cómo trabajar con el FAB en este entorno, actualizado a las prácticas modernas.

Incorporando las dependencias en Gradle

Para usar componentes de Material Design en el sistema de vistas, debes agregar la librería de Material Components para Android en tu archivo build.gradle.kts (o build.gradle):

// En build.gradle.kts (Groovy: implementation 'com.google.android.material:material:1.12.0')
implementation("com.google.android.material:material:1.12.0")

Nota que compile está obsoleto; ahora se usa implementation. Una vez modificado, Android Studio se sincronizará para descargar la librería.

Instanciando el botón flotante en el XML

Con la dependencia configurada, puedes agregar el FloatingActionButton a tu layout XML. La clase correcta a usar es com.google.android.material.floatingactionbutton.FloatingActionButton.

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Contenido de tu pantalla -->

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/my_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        app:srcCompat="@drawable/ic_add"
        android:contentDescription="Agregar" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Algunos puntos clave:

  • Se recomienda usar un CoordinatorLayout como contenedor raíz para permitir que el FAB interactúe correctamente con otros componentes como un Snackbar.
  • Se usa app:srcCompat en lugar de android:src para una mejor compatibilidad con vectores.
  • Puedes generar íconos fácilmente en Android Studio: clic derecho en res/drawableNewVector Asset.

Otros atributos importantes son app:fabSize (normal o mini) y app:backgroundTint para el color de fondo.

Usando el FloatingActionButton desde la Actividad o Fragmento

Para interactuar con el FAB desde tu código Kotlin o Java, la forma moderna y segura es usar View Binding.

Primero, habilítalo en tu archivo build.gradle.kts:

android {
    // ...
    buildFeatures {
        viewBinding = true
    }
}

Luego, en tu actividad, puedes acceder al botón de forma segura:

// Declaración de la variable de binding
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Inflar y establecer el layout
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // Acceder al FAB a través del binding
    binding.myFab.setOnClickListener { view ->
        Snackbar.make(view, "Tocaste el FAB", Snackbar.LENGTH_LONG).show()
    }
}

Este enfoque elimina la necesidad de findViewById, evitando errores de null pointer y type casting.

Animaciones en el Floating Action Button

Las animaciones siguen siendo una parte importante de la experiencia de usuario. Puedes animar el FAB de la misma manera que otros vistas, por ejemplo, para escalarlo al hacer clic.

val interpolador = AnimationUtils.loadInterpolator(baseContext,
       android.R.interpolator.fast_out_slow_in)

binding.myFab.setOnClickListener { view ->
   view.animate()
       .scaleX(0f)
       .scaleY(0f)
       .setInterpolator(interpolador)
       .setDuration(300)
       .withEndAction {
           view.animate()
               .scaleY(1f)
               .scaleX(1f)
               .setInterpolator(interpolador)
               .setDuration(300)
               .start()
       }
       .start()

   Snackbar.make(view, "Tocaste el FAB", Snackbar.LENGTH_LONG).show()
}

Este código Kotlin es más limpio y utiliza withEndAction para encadenar la animación de vuelta a su estado original.

escala float action button default

Posicionando en el borde de los contenedores

Una característica poderosa del CoordinatorLayout es la capacidad de "anclar" un FAB a otro componente. Esto es útil para crear layouts complejos donde el FAB se posiciona en relación con, por ejemplo, una AppBarLayout.

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/my_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_anchor="@id/app_bar"
    app:layout_anchorGravity="bottom|end"
    android:layout_margin="16dp"
    app:srcCompat="@drawable/ic_add" />

En este ejemplo, app:layout_anchor vincula el FAB al AppBarLayout con el id app_bar, y app:layout_anchorGravity define cómo se alinea con respecto a ese ancla.

borde de contenedor de float action button default

Convirtiendo el Floating Action Button en un Toolbar (Patrón Obsoleto)

En el pasado, existían librerías de terceros para transformar un FAB en una barra de herramientas flotante. Un ejemplo era com.github.rubensousa.floatingtoolbar.FloatingToolbar.

Aviso: Este patrón y las librerías asociadas (como la mencionada) ya no se mantienen y se consideran obsoletas. La comunidad de Android ha evolucionado hacia otros patrones de UI, como los menús contextuales o las hojas de diálogo inferiores (Bottom Sheets). Se desaconseja implementar esta funcionalidad de la manera que se describe en versiones antiguas de este artículo. El código se mantiene solo como referencia histórica.

float action button y toolbar

Ahora aprende a implementar tus diálogos (dialogs) en Android Studio.

Acepto recibir anuncios de interes sobre este Blog.

El botón de acción flotante de Android Studio es estupendo para resaltar acciones pertinentes en una pantalla, aprende a crear y usar este botón del Material Design, veamos variantes, evento click, forma, tamaños y más.

| 👤 Andrés Cruz

🇺🇸 In english