Guía completa de Flutter: El widget ElevatedButton


Avatar de Pedro Cortez

Añadir botones a tu aplicación Flutter es muy sencillo gracias al widget ElevatedButton. En esta guía, te enseño cómo crear un botón, redondearlo, añadirle una sombra y muchas cosas más.


elevattedbutton widget flutter

¿Cómo crear un botón con el widget ElevatedButton?

ElevatedButton es un widget básico de Flutter que, como su nombre indica, permite crear un botón. Este widget tiene múltiples parámetros para gestionar su forma y las acciones que realizará al hacer clic. Sin embargo, solo requiere dos parámetros para funcionar:

  • child → El contenido del botón, como un texto o un ícono;
  • onPressed → La acción que se ejecuta al hacer clic en el botón.

Aquí tienes un ejemplo sencillo de botón que muestra un texto al hacer clic:

import 'package:flutter/material.dart';

void main() => runApp(const ElevatedButtonEjemplo());

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(title: const Text("Ejemplo de ElevatedButton")),
       body: Center(
         child: Column(
           children: <Widget>[
             const SizedBox(height: 30),
             ElevatedButton(
               onPressed: () { print("¡Mi botón funciona!"); },
               child: const Text('Mostrar texto'),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

En Flutter, existen otros tipos de botones como TextButton e IconButton. Sin embargo, ElevatedButton permite lograr el mismo resultado y, en mi opinión, es más sencillo de usar en ciertos casos.

Dar color a un ElevatedButton

El widget ElevatedButton no tiene un parámetro de color directamente. Sin embargo, puedes usar su parámetro “style”, asignándole un valor con ElevatedButton.styleFrom(). Esta es la forma de personalizar, entre otras cosas, el color del botón, además de gestionar otros parámetros de estilo.

Aquí tienes un ejemplo:

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(title: const Text("Color ElevatedButton")),
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             ElevatedButton(
               onPressed: (){},
               child: const Text('Mostrar texto'),
               style: ElevatedButton.styleFrom(
                 backgroundColor: Colors.blueGrey,
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

Realizar una acción con una presión larga

Es posible que quieras realizar una acción diferente cuando el usuario mantenga pulsado el botón, como abrir un menú de opciones para eliminar, modificar o compartir un mensaje. Esto se logra mediante el parámetro onLongPress.

A continuación, un ejemplo sencillo donde una pulsación breve muestra un texto y una pulsación larga muestra otro mensaje:

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(title: const Text("Ejemplo de ElevatedButton")),
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             ElevatedButton(
               onPressed: () {
                 print("Mostrando mi mensaje");
               },
               onLongPress: () {print("Mostrando otro mensaje");},
               child: const Text('Enabled'),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

Redondear un ElevatedButton

Existen dos maneras de redondear un ElevatedButton. La primera consiste en usar el parámetro shape que proporciona este widget y aplicar el método RoundedRectangleBorder(). Este método tiene un parámetro borderRadius al cual se le asigna un valor mediante BorderRadius.circular(x). Cuanto mayor sea el valor de X, más redondeado será el botón.

Aquí tienes un ejemplo:

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             ElevatedButton(
               onPressed: () {},
               style: ElevatedButton.styleFrom(
                 backgroundColor: Colors.greenAccent,
                 shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.circular(10),
                 ),
               ),
               child: const Text(
                 "Botón redondeado",
                 textAlign: TextAlign.center,
                 style: TextStyle(
                   color: Colors.black,
                   fontWeight: FontWeight.bold,
                   fontSize: 18,
                 ),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

El inconveniente de este método es que, si el botón está dentro de un widget Container, puede que observes una ligera diferencia de color entre las dos capas.

Por eso, se recomienda redondear tanto el botón como su Container para evitar este problema:

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             Container(
               height: MediaQuery.of(context).size.height * 0.09,
               width: MediaQuery.of(context).size.width * 0.42,
               decoration: BoxDecoration(
                 borderRadius: BorderRadius.circular(10),
               ),
               child: ElevatedButton(
                 onPressed: () {},
                 style: ElevatedButton.styleFrom(
                   backgroundColor: Colors.greenAccent,
                   shape: RoundedRectangleBorder(
                     borderRadius: BorderRadius.circular(10),
                   ),
                 ),
                 child: const Text(
                   "Mi botón redondeado",
                   textAlign: TextAlign.center,
                   style: TextStyle(
                     color: Colors.black,
                     fontWeight: FontWeight.bold,
                     fontSize: 18,
                   ),
                 ),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

Agregar una sombra a mi botón

Es posible agregar una sombra debajo de tu botón colocándolo dentro de un Container, al cual puedes asignarle una sombra. Aunque el Container no dispone directamente de un parámetro de sombra, puedes usar BoxDecoration(), que sí incluye este parámetro. Luego, puedes personalizar el estilo de tu sombra mediante BoxShadow:

class ElevatedButtonEjemplo extends StatelessWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             Container(
               height: MediaQuery.of(context).size.height * 0.09,
               width: MediaQuery.of(context).size.width * 0.42,
               decoration: BoxDecoration(
                 boxShadow: [
                   BoxShadow(
                     color: Colors.black.withOpacity(0.2),
                     spreadRadius: 2,
                     blurRadius: 5,
                     offset: Offset(0, 5),
                   ),
                 ],
               ),
               child: ElevatedButton(
                 onPressed: () {},
                 style: ElevatedButton.styleFrom(
                   backgroundColor: Colors.greenAccent,
                 ),
                 child: const Text(
                   "Botón con sombra",
                   textAlign: TextAlign.center,
                   style: TextStyle(
                     color: Colors.black,
                     fontWeight: FontWeight.bold,
                     fontSize: 18,
                   ),
                 ),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

Cambiar el color de mi botón al hacer clic

Supongamos que deseas cambiar el color de un botón cuando el usuario hace clic (por ejemplo, para indicar su selección). Esto implica que el botón tendrá dos estados: seleccionado/no seleccionado, manejado mediante un valor booleano.

Para cambiar el color del botón al hacer clic, necesitas hacer tres cosas:

  1. Crear una variable booleana que almacene el estado de tu botón (true/false);
  2. Definir el color a mostrar si el valor es true y el color si es false;
  3. Cambiar el estado de la variable cuando el usuario hace clic en el botón.

En código, se vería así:

bool selected = true;

class ElevatedButtonEjemplo extends StatefulWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 State<ElevatedButtonEjemplo> createState() => _ElevatedButtonEjemploState();
}

class _ElevatedButtonEjemploState extends State<ElevatedButtonEjemplo> {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(title: const Text("Ejemplo de ElevatedButton")),
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             Container(
               height: MediaQuery.of(context).size.height * 0.09,
               width: MediaQuery.of(context).size.width * 0.42,
               child: ElevatedButton(
                 onPressed: () {
                   setState(() {
                     selected = !selected;
                   });
                   if (selected == true) {
                     print("Mi botón es verde");
                   }
                   if (selected == false) {
                     print("Mi botón es rojo");
                   }
                 },
                 style: ElevatedButton.styleFrom(
                   backgroundColor:
                     selected ? Colors.greenAccent : Colors.red,
                 ),
                 child: const Text(
                   "Mi botón",
                   textAlign: TextAlign.center,
                   style: TextStyle(
                     color: Colors.black,
                     fontWeight: FontWeight.bold,
                     fontSize: 18,
                   ),
                 ),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

setState solo puede ser utilizado en un StatefulWidget. Si tu widget es Stateless, necesitarás cambiarlo para implementar esta funcionalidad.

Crear un botón con un degradado de color

El parámetro backgroundColor no permite crear un degradado de color en un ElevatedButton. Así que, para lograrlo, podemos colocar nuestro botón dentro de un Container. Con el parámetro decoration de este Container, es posible usar la clase BoxDecoration(), que permite crear un degradado. Solo nos queda dar un fondo transparente al botón, y listo:

class ElevatedButtonEjemplo extends StatefulWidget {
 const ElevatedButtonEjemplo({super.key});

 @override
 State<ElevatedButtonEjemplo> createState() => _ElevatedButtonEjemploState();
}

class _ElevatedButtonEjemploState extends State<ElevatedButtonEjemplo> {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       body: Center(
         child: Column(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             const SizedBox(height: 30),
             Container(
               height: MediaQuery.of(context).size.height * 0.09,
               width: MediaQuery.of(context).size.width * 0.42,
               decoration: const BoxDecoration(
                 gradient: LinearGradient(
                   begin: Alignment.bottomRight,
                   end: Alignment.topLeft,
                   colors: <Color>[
                     Color.fromARGB(255, 134, 166, 239),
                     Color.fromARGB(255, 130, 238, 238),
                   ],
                 ),
               ),
               child: ElevatedButton(
                 onPressed: () {},
                 style: ElevatedButton.styleFrom(
                   backgroundColor: Colors.transparent,
                 ),
                 child: const Text(
                   textAlign: TextAlign.center,
                   "Mi botón",
                   style: TextStyle(
                     color: Colors.black,
                     fontWeight: FontWeight.bold,
                     fontSize: 18,
                   ),
                 ),
               ),
             ),
           ],
         ),
       ),
     ),
   );
 }
}

En este ejemplo, utilicé un degradado lineal, pero también es posible crear uno circular. Además, los puntos de inicio y fin del degradado se pueden modificar con los parámetros begin y end. Puedes usar tantas combinaciones de colores como desees para el degradado.

Conclusión

Ahora eres capaz de crear botones que permitirán a tus usuarios realizar diversas acciones. Con un poco de práctica, podrás desarrollar una aplicación móvil dinámica rápidamente.

¿Por qué no seguir aprendiendo y descubrir cómo crear cajas de selección (checkbox) para validar o invalidar opciones?

Avatar de Pedro Cortez