Cómo personalizar los botones FAB en Android: eliminando sombras y mejorando la apariencia con Material Design

La personalización de la interfaz de usuario en Android es crucial para crear aplicaciones atractivas y funcionales. En este artículo, nos centraremos en cómo manipular los botones de acción flotante (FAB) en Android, particularmente en cómo quitar la sombra, un aspecto que a menudo se busca para adaptar el diseño a estéticas más planas o integradas.

Ejemplo de un Floating Action Button sin sombra en Android

Comprendiendo los botones en Android

Un botón es un control con texto o imagen que realiza una acción cuando el usuario lo presiona. El texto que especifica su acción se debe especificar en el atributo android:text. Otros atributos importantes incluyen:

  • android:background: Se usa para cambiar el fondo del botón.
  • android:enabled: Determina si el botón está habilitado ante los eventos del usuario.

Tipos de botones en Material Design

En el diseño de Material Design, existen diferentes tipos de botones, cada uno con un propósito y apariencia específicos:

  • Raised buttons: Son los botones con elevación que hemos visto hasta ahora. Se usan sobre layouts que tienen gran variedad de contenido para delimitar las secciones o elementos.
  • Flat buttons (botones sin bordes): Tienen reacción de superficie pero no se elevan al ser presionados.
  • Floating Action Button (FAB): Tiene las mismas interacciones de elevación y ripple que el raised button, solo que este tiene forma circular.

Para añadir un botón en tu layout, puedes seguir estos pasos:

  1. Sitúate en la ventana Palette.
  2. Lleva el puntero del mouse hacia el layout y ubícalo según tu objetivo.
  3. Una vez elegido el lugar donde se ubicará el botón, confirma con un click su inserción.

Puedes abrir el layout actividad_botones.xml y agregar un botón centrado en el padre. Por ejemplo, puedes usar android:drawableLeft para ubicar una imagen a la izquierda del texto del botón.

Captura de pantalla del editor de layouts de Android Studio mostrando un botón centrado

Manejo de eventos de click en botones

Para añadir eventos de click a un botón, primero debes estudiar la clase Button que es la encargada de representar botones en la UI. Luego, verás cómo añadir eventos de click.

Comienza por añadir un TextView al layout. Lo siguiente es dirigirse al layout y asignar el método en el botón con android:onClick. Luego invoca el método setOnClickListener() desde la instancia y como parámetro digita solamente "new O". Así podrás sobrescribir el controlador onClick() para que tenga un alcance global para todos los views que pertenezcan al contenedor. Ahora dentro del controlador crea un nuevo Intent para iniciar una nueva actividad.

La solución manual sería escribir la firma y cuerpo del método como es requerido. Una forma común es abrir un switch con el ID del view clickeado y elegir el color dependiendo del caso. Puedes poner 4 botones centrados horizontalmente y uno debajo de otro dentro del relative layout.

Eventos clic en boton (OnClickListener) - Tutorial Android

Jetpack Compose y Material Design 3 para un control avanzado

Jetpack Compose compila las IUs con componentes de Material Design listos para usar. Compose es una combinación de IDs de grupo de Maven en androidx.compose.material y androidx.compose.material3. Material 3 es la siguiente evolución de Material Design, e incluye temas y componentes actualizados, así como funciones de personalización de Material You, como el color dinámico.

Para agregar una dependencia en Compose, debes añadir el repositorio de Maven de Google a tu proyecto. Tus comentarios ayudan a mejorar Jetpack. Avísanos si descubres nuevos errores o tienes ideas para mejorar esta biblioteca. Consulta los errores existentes de esta biblioteca antes de crear uno nuevo.

Novedades y versiones de Compose Material

A lo largo del tiempo, se han lanzado diversas versiones de androidx.compose.material:material-*, con mejoras significativas. Por ejemplo, la versión 1.11.0-rc01 y sus predecesoras (beta y alpha) han introducido optimizaciones y correcciones. La versión 1.10.0-rc01 y sus previas movieron el valor predeterminado de minSdk de la API 21 a la API 23. Las verificaciones de Lint incluidas en Compose ahora requieren una versión mínima de AGP de 8.8.2. Si no puedes actualizar AGP, puedes actualizar Lint por separado usando android.experimental.lint.version=8.8.2 (o una versión más reciente) en tu archivo gradle.properties. Los proyectos lanzados con Kotlin 2.0 requieren que se consuma KGP 2.0.0 o una versión posterior.

Las APIs de cuadros de decoración de campos de texto ya no son experimentales. ExposedDropdownMenu es compatible a nivel binario con versiones anteriores. Los hipervínculos en Text(AnnotatedString) ahora tienen el diseño de Material de forma predeterminada. Se dejó de usar runWithTimingDisabled en favor de runWithMeasurementDisabled, que describe con mayor claridad el comportamiento: todas las métricas están pausadas. Además, expón la superclase MicrobenchmarkScope, ya que no es posible volver a declarar la función runWithMeasurementDisabled para abrir el acceso, ya que está intercalada. Se corrigió una falla en los indicadores de progreso y carga en caso de que se pase un Float.NaN como progreso.

Las versiones 1.8.0 y subsiguientes han traído cambios de comportamiento que afectarán la forma en que los componentes que tienen en cuenta la inserción se comportan alrededor de un corte de pantalla. Objetos predeterminados para Material 2 y Material 3. Si este cambio causa un comportamiento no deseado, especifica manualmente el parámetro WindowInsets para cada componente. La actividad que se usa como host para el elemento componible en prueba cuando se usa ComposeContentTestRule.setContent ahora usa el tema Theme.Material.Light.NoActionBar para evitar que ActionBar se superponga con el contenido de la prueba cuando se segmenta el SDK 35. Para inhabilitar este comportamiento, puedes quitar la dependencia de ui-test-manifest y agregar una entrada de actividad en el AndroidManifest.xml de tu app de prueba para ComponentActivity con el tema que elijas.

Gráfico de evolución de versiones de Jetpack Compose

Expose sheetGesturesEnabled en ModalBottomSheetLayout. Se corrigió el problema por el que, a veces, no se seguían los modificadores de tamaño del campo de texto. Se optimizó el comportamiento de Scaffold contentPadding para evitar la recomposición constante del contenido del cuerpo cuando cambia contentPadding. Haz que el control deslizador de Material cambie su valor cuando se presionen las teclas de control. Se quitó readOnly de TextFields para fijar la versión de la base estable. Se agregó compatibilidad con ondas en componentes que se expanden en Android S+, como una tarjeta que se expande cuando se hace clic en ella. Anteriormente, la onda no llenaba el nuevo tamaño, pero ahora se expandirá a los nuevos límites.

Los componentes de Material que antes aceptaban un MutableInteractionSource y establecían remember { MutableInteractionSource() } como valor predeterminado ahora aceptan un MutableInteractionSource que puede ser nulo y establecen el valor nulo como valor predeterminado. Si no estás elevando y usando MutableInteractionSource, debes pasar null. Esto permite que algunos componentes creen una instancia de forma diferida solo cuando sea necesario, lo que mejora el rendimiento.

Mejoras en el diseño de texto y componentes

Se actualizó la API para obtener vínculos con temas de Material en Text. Específicamente, se quitaron los métodos de TextDefaults para construir LinkAnnotations con temas y analizar HTML con vínculos con temas. En su lugar, se agregó una clase TextLinkStyles que permite diseñar los vínculos como un parámetro para el elemento componible Text. Se corrigió el problema por el que backgroundColor no se aplicaba a TextFieldDecorationBox y OutlinedTextFieldDecorationBox. Las cajas de decoración ahora aceptan un parámetro shape. Se quitó RippleConfiguration#isEnabled y se permitió que LocalRippleConfiguration sea nulo. Para inhabilitar una onda, en lugar de proporcionar un RippleConfiguration con isEnabled = false, proporciona null a LocalRippleConfiguration.

Los vínculos de texto tienen una opción de diseño de estado presionado, además del diseño normal, el diseño de desplazamiento y el diseño de enfoque. Los métodos TextDefaults tienen un argumento pressedStyle para admitir esa función. El padding superior de OutlinedTextField para la etiqueta ahora tiene en cuenta el tamaño de la fuente del sistema. androidx.compose.material ya no requiere usar la misma versión de cada artefacto en este grupo de Maven. Se movieron más valores predeterminados de ModalDrawer y BottomDrawer al objeto DrawerDefaults. Se quitó la marca ScaffoldSubcomposeInMeasureFix.

Ejemplo de un TextLinkStyle personalizado en Jetpack Compose

Navegación y rendimiento con Compose Material

Se agregó un nuevo artefacto androidx.compose.material:material-navigation que añade compatibilidad con las hojas inferiores como destinos cuando se usa Navigation Compose. Esta biblioteca reemplaza a la biblioteca de Accompanist Navigation Material. BottomDrawer se promovió de experimental a estable. BottomDrawerState ahora expone el progreso como una función, lo que permite consultar el progreso entre objetivos específicos. BottomDrawerState ahora permite personalizar la especificación de animación, y confirmStateChange ya no es una expresión lambda final. BackdropScaffold se promovió de experimental a estable. La especificación de animación ahora es una especificación de tween de acuerdo con los lineamientos. El parámetro snackbarHost de BackdropScaffold ya no es el último parámetro para evitar confusiones con las expresiones lambda finales. BackdropScaffoldState expone una API de progress(from, to) para consultar el progreso entre anclajes. Las hojas inferiores estándar pasaron de ser experimentales a estables. Se quitaron los constructores obsoletos. La especificación de animación ahora es una especificación de interpolación según los lineamientos. Las hojas inferiores modales pasaron de experimentales a estables. Se quitaron los constructores obsoletos. La especificación de animación ahora es una especificación de tween de acuerdo con los lineamientos.

Se solucionó un problema por el que BackdropScaffold podía fallar en situaciones específicas en combinación con LookaheadScope. Se quitó la subcomposición dentro de BottomSheetScaffold para mejorar el rendimiento. Se corrigió un problema por el que BottomSheetScaffold fallaba en situaciones específicas en combinación con LookaheadScope. Se quitó la subcomposición dentro de ModalBottomSheetLayout, lo que mejoró el rendimiento. Se dejó de usar una función materialIcon en favor de su sobrecarga que toma un parámetro autoMirror. Se aumentó automáticamente la altura del elemento de navegación para contenido grande. Se quitó la funcionalidad relacionada con el panel lateral de BottomSheet.

Eliminando sombras en los Floating Action Buttons

Ya viste algunos atributos que puedes cambiar en los botones para transformar su apariencia. Y el botón presionado es exactamente lo mismo. Con esos drawables listos, ahora puedes ir al layout de la actividad y modificar el atributo android:background para asignar la lista de drawables personalizados.

Para quitar la sombra de un FAB, especialmente en el contexto de Jetpack Compose y Material Design 3, la clave reside en cómo se maneja la elevación. Los FAB por defecto tienen una elevación que crea una sombra. Al manipular esta elevación a cero, la sombra desaparecerá.

En Jetpack Compose, un FloatingActionButton puede recibir un parámetro elevation. Si se establece en 0.dp, la sombra se eliminará. También puedes controlar la elevación para diferentes estados (presionado, enfocado, etc.) usando los modificadores correspondientes. Por ejemplo, al definir un FloatingActionButton, puedes especificar elevation = 0.dp para eliminar la sombra predeterminada.

Es importante destacar que el Material Design 3 y sus componentes permiten un control más granular sobre estos aspectos visuales, facilitando la creación de interfaces que se ajusten precisamente a la visión del diseñador.

tags: #quitar #sombra #fab #button #android