Texto de: Lucas Galdino
Introdução
Já faz um tempo desde que o Flutter modificou os botões em uma de suas atualizações. Os antigos botões passaram algum tempo ainda podendo ser utilizados, porém, com avisos de “deprecated”, e hoje em dia já não são mais utilizáveis, o que nos leva a aprender sobre os novos botões. Vamos lá, falar um pouco sobre essas mudanças e conhecer melhor cada um desses botões.
Criando o projeto
Para ilustrar cada um dos botões vou iniciar criando um pequeno e simples projeto. O comando será o seguinte:
flutter create botoes
Vou fazer algumas pequenas modificações no projeto base para ter espaço para os exemplos do artigo. Exemplos que irão ficar dentro do "children" do widget "Column" lá do final do código. Aqui a versão inicial do arquivo "main.dart":
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Botões',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: Colors.deepPurple,
),
useMaterial3: true,
),
home: const MyHomePage(title: 'Botões'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [],
),
),
);
}
}
O resultado no emulador ficou assim:
TextButton
Começarei pelo TextButton, antes conhecido por FlatButton, que é um trecho de texto puro que serve como botão. Criei dois botões, um ativo e outro inativo. O ativo contém uma função vazia no "onPressed" enquanto o inativo recebeu "null" nessa propriedade, fazendo com que de fato ele fique inativo. Lembrando que sempre vou estar ajustando o uso da palavra "const" para evitar os warnings do VSCode. Aqui o código para os botões do tipo TextButton:
TextButton(
onPressed: () {},
child: const Text('TextButton Ativo'),
),
const TextButton(
onPressed: null,
child: Text('TextButton Inativo'),
),
O resultado na tela do aplicativo será o seguinte:
Como esse tipo de botão é mais simples e utilizado quando queremos de fato um texto, a sua customização pode ser tão simples quanto. Claro, é possível adicionar um background e coisas do tipo, mas caso o tipo de botão desejado seja um que tenha background, é melhor utilizar outro tipo e não o TextButton, logo, só modifiquei as cores do texto para indicar um pouco da customização possível nesse tipo de botão.
TextButton(
onPressed: () {},
child: const Text(
'TextButton Ativo',
style: TextStyle(color: Colors.green),
),
),
TextButton(
onPressed: null,
child: Text(
'TextButton Inativo',
style: TextStyle(color: Colors.red[200]),
),
),
O resultado na tela é o seguinte:
ElevatedButton
Antes de passar para o próximo exemplo, vou adicionar o widget “Divider” logo abaixo dos dois exemplos anteriores, para podermos separar visualmente cada exemplo na tela do aplicativo.
const Divider(),
Agora vamos para o ElevatedButton, antigamente conhecido como RaisedButton, aqui já temos uma diferença bem clara, o background no texto do botão. Farei como no exemplo anterior, iniciando com um botão ativo e outro inativo, aqui o código:
ElevatedButton(
onPressed: () {},
child: const Text('ElevatedButton Ativo'),
),
const ElevatedButton(
onPressed: null,
child: Text('ElevatedButton Inativo'),
),
Falta código
Nesse botão podemos aplicar melhor uma customização, afinal temos elementos visuais mais chamativos que podem ser editados. Podemos adicionar a propriedade "style" nos botões. No ativo, adicionei verde como cor para o background, adicionei também uma pequena sombra verde e utilizei o "elevation" para poder deixar a sombra mais visível. No botão inativo as coisas ficam um pouco mais limitadas justamente por conta desse estado de inativo, algumas propriedades só irão ser aplicadas a botões ativos. Aqui apenas modifiquei a cor para vermelho. Também alterei as cores dos textos para poder melhorar a legibilidade.
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green[700],
shadowColor: Colors.green,
elevation: 3,
),
onPressed: () {},
child: const Text(
'ElevatedButton Ativo',
style: TextStyle(color: Colors.white),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
disabledBackgroundColor: Colors.red[800],
),
onPressed: null,
child: Text(
'ElevatedButton Inativo',
style: TextStyle(color: Colors.grey[400]),
),
),
Aqui o resultado no emulador:
OutlinedButton
O próximo exemplo é o OutlinedButton, antes conhecido como OutlineButton, sim, só adicionaram uma letra nessa mudança. Esse botão é bem similar Ao exemplo anterior, porém ao invés de termos todo o background, temos apenas uma linha circulando o texto utilizado. Aqui o código para mais exemplos ativos e inativos:
OutlinedButton(
onPressed: () {},
child: const Text('OutlinedButton Ativo'),
),
const OutlinedButton(
onPressed: null,
child: Text('OutlinedButton Inativo'),
),
E o resultado na tela do emulador:
Para modificar um pouco esse exemplos irei trocar o formato da borda de cada botão e trocar também as cores do texto e das bordas de cada um. No ativo coloquei as cores verdes e criei uma borda retangular arredondada. Enquanto no inativo coloquei novamente as cores vermelha e utilizei uma borda oval. Aqui o código:
OutlinedButton(
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.green),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
onPressed: () {},
child: const Text('OutlinedButton Ativo',
style: TextStyle(color: Colors.green)),
),
OutlinedButton(
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.red),
shape: const OvalBorder(),
),
onPressed: null,
child: const Text('OutlinedButton Inativo',
style: TextStyle(color: Colors.red)),
),
E o resultado na tela:
IconButton
Existe também o IconButton, que como o nome diz, utiliza-se de um ícone para indicar o botão. Existem diversas variações desse daqui, então para não estender muito o artigo vou apenas citar e dar um pequeno exemplo dele, certo? Ele pode virar assunto principal em outro artigo quem sabe. Aqui o código de dois botões do tipo Icon, um ativo com um ícone de Sol e outro inativo com o ícone de Lua.
IconButton(
onPressed: () {},
icon: const Icon(Icons.sunny),
),
const IconButton(
onPressed: null,
icon: Icon(Icons.dark_mode),
),
E o resultado no aplicativo:
Vou deixar também o código final do arquivo "main.dart" utilizado no artigo:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Botões',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: Colors.deepPurple,
),
useMaterial3: true,
),
home: const MyHomePage(title: 'Botões'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {},
child: const Text(
'TextButton Ativo',
style: TextStyle(color: Colors.green),
),
),
TextButton(
onPressed: null,
child: Text(
'TextButton Inativo',
style: TextStyle(color: Colors.red[200]),
),
),
const Divider(),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green[700],
shadowColor: Colors.green,
elevation: 3,
),
onPressed: () {},
child: const Text(
'ElevatedButton Ativo',
style: TextStyle(color: Colors.white),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
disabledBackgroundColor: Colors.red[800],
),
onPressed: null,
child: Text(
'ElevatedButton Inativo',
style: TextStyle(color: Colors.grey[400]),
),
),
const Divider(),
OutlinedButton(
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.green),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
onPressed: () {},
child: const Text('OutlinedButton Ativo',
style: TextStyle(color: Colors.green)),
),
OutlinedButton(
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.red),
shape: const OvalBorder(),
),
onPressed: null,
child: const Text('OutlinedButton Inativo',
style: TextStyle(color: Colors.red)),
),
const Divider(),
IconButton(
onPressed: () {},
icon: const Icon(Icons.sunny),
),
const IconButton(
onPressed: null,
icon: Icon(Icons.dark_mode),
),
],
),
),
);
}
}
Conclusão
Então é isso, esses são os principais botões utilizados dentro das interfaces em geral com o Flutter. Existem diversas maneiras de se utilizar e até variações de cada um deles. Não cabe tudo aqui nesse pequeno artigo, mas super vale uma pesquisa para conhecer mais ainda cada um deles. Bons estudos!