Hace un tiempo, revisando un código de cliente, me encontré con la típica situación: un botón que simplemente tenía que ser redondo, o al menos con las esquinas suavizadas, y la implementación era un festival de verbosidad. Vi un MaterialStateProperty.all metido en todos lados, y pensé: «¿De verdad esto es lo más directo para algo tan básico?». Me quema un poco ver cómo a veces la solución más aceptada o la que tiene más votos en un foro no es la más práctica para el 90% de los casos. Te juro que yo mismo caí en eso al principio, copiando y pegando sin cuestionar. Esto me costó un par de horas entenderlo de verdad, pero prefiero compartirlo para que no te pase.
El problema no es que la gente quiera hacer cosas raras. La mayoría solo quiere un botón con un borderRadius, algo súper común en cualquier diseño. Pero entre las deprecaciones de Flutter 2.0 y las mil formas de hacer lo mismo, uno se pierde. Antes teníamos RaisedButton y FlatButton, que eran más directos en su momento. Ahora, el equipo de Flutter los cambió por ElevatedButton, OutlinedButton y TextButton. Y está bien, son más consistentes con Material Design 3. Pero la forma de estilizarlos cambió y, para mí, algunos se fueron por el camino más largo.
Si buscas cómo redondear un botón en Stack Overflow (y lo he hecho), lo más probable es que te encuentres con algo como esto:
ElevatedButton(
onPressed: () {},
child: const Text('Mi Botón Redondo'),
style: ButtonStyle(
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: const BorderSide(color: Colors.red)
)
)
)
)
No voy a decir que esto esté mal. Funciona. Pero, honestamente, para un simple borderRadius, es mucha vuelta. El MaterialStateProperty.all es necesario cuando quieres que el estilo del botón cambie dependiendo de su estado (si está presionado, deshabilitado, enfocado, etc.). Ahí tiene todo el sentido del mundo. Pero si solo quieres que tus botones tengan esquinas redondeadas siempre, ¿es la forma más legible o concisa?
En mi experiencia, y lo que yo uso en mis proyectos y con mis clientes, es el método .styleFrom() que tienen los propios botones. Es mucho más directo y legible para casos de estilo estático. Mira la diferencia:
ElevatedButton(
onPressed: () {},
child: const Text('Mi Botón Redondo'),
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
side: const BorderSide(color: Colors.red), // Opcional: para un borde
backgroundColor: Colors.blue, // Y puedes poner más estilos aquí
foregroundColor: Colors.white,
),
)
¿Notas la diferencia? En lugar de envolver todo en un ButtonStyle y luego en un MaterialStateProperty.all, el ElevatedButton.styleFrom() ya te da un objeto ButtonStyle con valores por defecto y te permite sobrescribir las propiedades de forma más limpia. De hecho, internamente ya maneja el MaterialStateProperty.all por ti para estas propiedades básicas, simplificando la interfaz.
Para casos específicos, como un botón ovalado tipo píldora (o «stadium»), ni siquiera necesitas un RoundedRectangleBorder; tienes el StadiumBorder():
ElevatedButton(
onPressed: () {},
child: const Text('Botón Píldora'),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
// otros estilos...
),
)
Este mismo patrón aplica para OutlinedButton.styleFrom() y TextButton.styleFrom(). Es un patrón consistente. A mí me convence mucho más porque reduce la verbosidad y hace el código más fácil de leer a primera vista. Cuando abro un archivo y veo un .styleFrom(), sé que estoy viendo estilos estáticos y me ahorro el esfuerzo mental de procesar el MaterialStateProperty.all.
Mi consejo es este: no te quedes siempre con la primera solución que encuentres, por muy votada que esté. Piensa si es la más simple y directa para lo que necesitas. Muchas veces, la gente se equivoca usando la solución más compleja para un problema sencillo, solo porque funciona o porque alguien más la usó. Eso es sobreingeniería de estilo, y a la larga, te hace el código más difícil de mantener y entender. Para algo tan básico como un borderRadius, usa lo que te ahorre líneas y dolor de cabeza.