E aí pessoal! Para quem ainda não atualizou suas versões, desde a versão 1.22 do Flutter alguns botões foram trocados por novos e agora estão deprecated. Essa mudança começou na versão 1.22 do Flutter, mas logo em seguida foi lançado o Flutter 2, que manteve essas mudanças e são consideradas o novo padrão.
Nesse artigo vamos conhecer quais foram as mudanças no botões no Flutter 2.
Criação do projeto
Vou criar um projeto do zero com o comando:
flutter create buttons
Vou deletar a pasta ‘test’ e editar apenas o arquivo ‘main.dart’ do projeto.
O código inicial do arquivo ‘main.dart’ será o seguinte:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Buttons',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Buttons'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [],
),
),
);
}
}
Lembrando que fiz o mínimo de edições do código padrão criado pelo próprio Flutter. Aviso de antemão que os prints serão de dois emuladores diferentes, pois estou trabalhando ao mesmo tempo em um PC com o Flutter 1.21 e em um Macbook com o Flutter 2.0.1, dessa forma vou conseguir mostrar as mudanças nas versões.
TextButton no lugar de FlatButton
Primeiramente, vou criar dois botões da forma antiga. Um botão com uma função vazia ligada a ele, para poder ficar ativa; e outro botão apontando para null, ficando inativo. Dessa forma teremos uma base para refazer os botões antigos com a nova versão.
Farei os dois botões de forma bem simples, dentro da ‘Column’ que está vazia no código principal ali de cima:
FlatButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('FlatButton Ativo'),
onPressed: () {},
),
FlatButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('FlatButton Inativo'),
onPressed: null,
),
O resultado na tela do App será o seguinte:
Já no Flutter 2, no seu VSCode o resultado atualizado é o seguinte:
Temos a famosa mensagem de ‘deprecated‘ e a sugestão para substituir pelo TextButton.
O primeiro aviso nos diz que apenas trocar o tipo do botão não é suficiente para que tudo funcione corretamente.
A mudança começa agora. Ao invés de modificar a aparência do botão conforme suas propriedades, como ‘color’ ou ‘textColor’, vamos modificar a a aparência a partir de um ‘style’.
No código abaixo, modifiquei os dois botões adicionando cores e sombra aos dois dessa forma. Também modifiquei um pouco o estilo no Widget ‘Text’, pois é lá que modificaremos o texto do botão a partir de agora.
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.red,
elevation: 15,
shadowColor: Colors.green),
child: Text(
'FlatButton Ativo',
style: TextStyle(
color: Colors.black,
),
),
onPressed: () {},
),
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.amber,
elevation: 15,
shadowColor: Colors.purple,
),
child: Text(
'FlatButton Inativo',
style: TextStyle(
color: Colors.black,
),
),
onPressed: null,
),
O resultado na tela é o seguinte:
Para deixar igual aos botões anteriores, os FlatButtons, que mostrei anteriormente basta deixar o código assim:
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
),
child: Text(
'FlatButton Ativo',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {},
),
TextButton(
style: TextButton.styleFrom(),
child: Text(
'FlatButton Inativo',
),
onPressed: null,
),
E o resultado será o seguinte:
O código final do arquivo ‘main.dart’ nessa parte dos TextButton ficará assim:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Buttons',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Buttons'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
),
child: Text(
'FlatButton Ativo',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {},
),
TextButton(
style: TextButton.styleFrom(),
child: Text(
'FlatButton Inativo',
),
onPressed: null,
),
],
),
),
);
}
}
ElevatedButton no lugar de RaisedButton
Nesse caso é bem parecido do anterior. Primeiro vou mostrar como seria feito antes do Flutter 2. O código do arquivo ‘main.dart’ será o seguinte:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Buttons',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Buttons'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('RaisedButton Ativo'),
onPressed: () {},
),
RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('RaisedButton Inativo'),
onPressed: null,
),
],
),
),
);
}
}
E o resultado no emulador será o seguinte:
Na versão 2 do Flutter teremos aquele mesmo problema de antes.
Novamente, não funcionará apenas se trocarmos o tipo do botão:
Se deixarmos o código dos botões sem estilo nenhum, apenas com o seu ‘child’ e a função do ‘onPressed’, o resultado vai de acordo com as cores primárias do seu projeto.
ElevatedButton(
child: Text('RaisedButton Ativo'),
onPressed: () {},
),
ElevatedButton(
child: Text('RaisedButton Inativo'),
onPressed: null,
),
E o resultado na tela fica assim:
Agora vamos aplicar nosso ‘style’ nos botões. Aqui as coisas são um pouco diferentes, mas antes de explicar vou mostrar o código e o resultado na tela. Usei o ‘SizedBox()’ apenas para gerar um espaçamento entre os botões mesmo.
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
onSurface: Colors.green,
elevation: 20,
shadowColor: Colors.red,
),
child: Text('RaisedButton Ativo'),
onPressed: () {},
),
SizedBox(height: 40),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
onSurface: Colors.green,
elevation: 20,
shadowColor: Colors.red,
),
child: Text('RaisedButton Inativo'),
onPressed: null,
),
Notem que mesmo que os botões tenham o mesmo estilo o resultado foi bem diferente. O que acontece é que as propriedades ‘primary’, ‘elevation’ e ‘shadowColor’ serão aplicadas quando o botão estiver ativo, ou seja, quando tiver alguma função ligada a ele. Enquanto que a propriedade ‘onSurface’ é ligada ao fundo do botão quando inativado, ou seja, quando não temos nenhuma função ligada a ele.
Para deixar os ElevatedButtons iguais aos RaisedButtons do primeiro exemplo, basta deixar o código sem estilo. Esse é o visual padrão deles, que vão de acordo com o PrimaryColor do seu projeto.
É isso, pessoal! Com essas pequenas modificações vocês vão conseguir atualizar seus botões no Flutter 2!
Bons estudos!