Flutter - Aplicação : Gasolina ou Álcool
Hoje veremos uma aplicação que permite indicar ao usuário qual o combustível é mais vantajoso para abastecer. |
|
O Flutter é um SDK de aplicativo móvel do Google que ajuda a criar aplicativos móveis modernos para iOS e Android usando uma única (quase) base de código.
Se você não conhece o Flutter veja o meu artigo : Flutter - Primeiros contatos e impressões
Gasolina ou Álcool ?
Vamos iniciar mostrando a aplicação funcionando para que você tenha uma visão do que iremos construir neste artigo:
A aplicação é bem simples, ela recebe a informação do preço da gasolina e do álcool, a seguir ela divide o preço do álcool pelo da gasolina e se o valor for superior a 0.70 então a gasolina é mais vantajosa, caso contrário o álcool seria mais vantajoso.
Para ter uma idéia do layout podemos usar a ferramenta de renderização visual para nos ajudar a visualizar melhor o layout.
Tecle CTRL+SHIFT+P e a seguir selecione : Toggle Debug Painting
Essa opção ativa linhas azuis no emulador permitindo que você visualize as partes do seu layout.
Em termos de layout, a aplicação também é simples pois temos apenas um Widget Column que contém dois widgets TextFormFields, um widget RaisedButton e um widget Text. E na barra da aplicação temos um ícone.
Embora seja bem simples, podemos aprender conceitos importantes relacionados ao Flutter nesta aplicação, dentre os quais :
Assim vamos então iniciar a criação desta aplicação no Flutter.
Recursos usados:
Criando a aplicação : Gasolina ou Álcool ?
Parar criar o projeto usado neste exemplo abra o Visual Studio Code e tecle CTRL+ SHIFT+P para abrir a paleta de comandos e a seguir selecione a opção : Fluter:New ProjectA seguir informe o nome do projeto : flutter_combustivel e tecle ENTER
Na janela de
diálogo a seguir selecione a pasta onde o projeto vai ser salvo e clique em :
Select a folder to create the project in
O Flutter vai criar um projeto padrão onde todo o código da aplicação vai estar no arquivo main.dart dentro da pasta lib do projeto.
Vamos substituir o código gerado no arquivo main.dart pelo código abaixo:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.blue),
home: Home() ,
);
}
}
|
Temos neste código um StatelessWidget chamado MyApp que usa o MaterialApp onde estamos desabilitando o aviso de modo debug, definindo um tema com uma cor de fundo azul, e usando o widget home para definir a rota principal da aplicação. No caso estamos definindo o widget Home que iremos criar a seguir.
Como nossa aplicação vai interagir com o usuário e vai ter o seu estado alterado vamos criar um StatefulWidget chamado Home mas vamos fazer isso em outro arquivo.
Crie um arquivo chamado widget_combustivel.dart na pasta lib do projeto.
A seguir inclua o import para 'package:flutter/material.dart'
A seguir no Visual Studio Code digite stf e a seguir selecione a opção : Flutter stateful widget
Isso vai gerar o trecho de código padrão para um StatefullWidget. A seguir basta digitar o nome do widget.
Digite Home e você deverá ver o código abaixo:
Neste momento nossa tela de login tem apenas um Container vazio e se executarmos a nossa aplicação agora iremos obter apenas uma tela preta.
Antes de executar abra o arquivo main.dart na pasta lib e inclua a referência ao pacote que referencia nosso widget de login:
Neste momento nosso projeto possui o arquivo main.dart e o arquivo widget_combustivel.dart onde iremos agora definir o layout da nossa aplicação.
Definindo o layout
Vamos iniciar a definição do layout da nossa aplicação.
Fazendo um esboço do nosso layout temos que ter :
- Layout
centralizado com cor de fundo
- Uma barra com o título ~ 'Gasolina ou Álcool ?'
- Um ícone para resetar as informações do formulário
- Um ícone de um veículo centralizado no topo da tela;
- Dois
widgets TextFormFields para entrada do usuário um sobre o outro com textos;
- Nas duas entradas teremos a exibição de um teclado numérico;
- Um
Button com com o texto 'Calcular' ;
Assim, para começar, teremos que :
a- Substituir
o widget Container pelo
Scaffold
b- Definir o backgroundColor com a cor desejada que
para o exemplo é orange;
c- Definir o widget AppBar com o título;
d- centralizar o título;
e- definir a cor de fundo usando backgroundColor;
f- incluir uma action e definir o ícone Refresh;
g- definir a cor de fundo como white;
h- Definir um child Column do body para empilhar o
texto usando e definir o alinhamento como centralizado
i- A seguir vamos definir como filhos de Column os
widgets TextFormField, RaisedButton e Text. Para o
código ficar mais legível vamos definir os métodos :
buildTextFormFieldAlcool(), buildTextFormFieldGasolina(),
buildContainerButton(context) e buildTextInfo()
Vamos alterar o código do arquivo widget_combustivel.dart conforme abaixo:
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Gasolina ou Alcool ?"),
centerTitle: true,
backgroundColor: Colors.orange,
actions: <Widget>[
IconButton(icon: Icon(Icons.refresh), onPressed: () {})
],
),
backgroundColor: Colors.white,
body: SingleChildScrollView(
padding: EdgeInsets.fromLTRB(25.0, 0.0, 25.0, 0.0),
child: Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.directions_car, size: 60.0, color: Colors.deepOrange),
buildTextFormFieldGasolina(),
buildTextFormFieldAlcool(),
buildContainerButton(context),
buildTextInfo()
],
),
),
),
);
}
Text buildTextInfo(){
}
Text buildTextFormFieldGasolina(){
}
Text buildTexAlcool(){ } Text buildContainerButton(Context){ } } |
Neste código além do que já foi descrito precisamos usar no body um SingleChildScrollView() e incluir espaços de 25.0 à esquerda (Left) e à direita (Right) usando padding: EdgeInsets.fromLTRB(25.0, 0.0, 25.0, 0.0).
A seguir definimos o widget Column como filho de um widget Form pois vamos precisar fazer a validação dos campos TextFormField. Além disso criamos um contêiner para os campos usando key e atribuindo o valor _formkey que iremos definir mais adiante e que também iremos usar para validar o formulário.
No widget Column definimos crossAxisAlignment: CrossAxisAlignment.stretch para que widgets ocupem todo o espaço da tela.
Agora vamos definir o código de cada um dos métodos usados.
1- buildTextFormFieldAlcool
TextFormField buildTextFormFieldAlcool() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "Preço do Álcool",
labelStyle: TextStyle(color: Colors.black, fontSize: 20.0),
),
controller: alcoolController,
validator: (value) {
if (value.isEmpty) {
return 'Informe o valor do álcool';
}
return null;
},
);
}
|
2- buildTextFormFieldGasolina
TextFormField buildTextFormFieldGasolina() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: "Preço da Gasolina",
labelStyle: TextStyle(color: Colors.black, fontSize: 20.0),
),
controller: gasolinaController,
validator: (value) {
if (value.isEmpty) {
return 'Informe o valor da gasolina';
}
return null;
},
);
}
|
Nestes dois métodos definimos um TextFormField para entrada de dados pelo usuário onde aplicamos um decoration e definimos um controller(TextEditingController) para poder obter e tratar o valor informado pelo usuário.
Para retornar o valor informado em um TextField estamos usando um TextEditingController e temos que cumprir as seguintes etapas:
Iremos definir o TexteditingController para cada campo no início do arquivo.
A seguir definimos a validação de cada um dos campos usados de forma a não aceitar valores vazios.
3- buildContainerButton
Container buildContainerButton(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
height: 60.0,
child: RaisedButton(
onPressed: (){
if(_formkey.currentState.validate()){
calcula();
FocusScope.of(context).requestFocus(new FocusNode());
}
},
child : Text("Calcular",
style: TextStyle(
color: Colors.white, fontSize: 20.0
)),
color: Colors.orange,
),
);
}
|
Aqui definimos o widget Container como pai do widget RaisedButton, e incluímos espaço acima e abaixo definindo também uma altura de 60.0 para que o botão ficasse com o tamanho adequado.
No callback onPressed() estamos verificando se os dados são válidos e chamando o método calcula() que vai realizar o cálculo com os valores informados.
A seguir usamos o código para ocultar o teclado numérico usado para informar os dados.
3- buildTextInfo
Text buildTextInfo() {
return Text(_infoText,
textAlign: TextAlign.left,
style: TextStyle( color:Colors.black, fontSize: 20.0)
);
}
|
Aqui o widget Text exibe o conteúdo da variável privada _infoText que vamos definir no ínicio do arquivo.
Precisamos agora definir na classe _HomeState que herda de State as seguintes varíaveis e métodos:
A seguir temos a implementação de cada um destes membros:
GlobalKey<FormState> _formkey = GlobalKey<FormState>();
TextEditingController gasolinaController = TextEditingController();
TextEditingController alcoolController = TextEditingController();
String _infoText="Informe o valor de cada combustível";
void _resetFields() {
gasolinaController.text="";
alcoolController.text="";
setState(() {
_infoText="Informe o valor de cada combustível";
_formkey = GlobalKey<FormState>();
});
}
void calcula() {
setState(() {
double gasolina = double.parse(gasolinaController.text);
double alcool = double.parse(alcoolController.text);
double resultado = (alcool/gasolina);
if( resultado > 0.70) {
_infoText="Percentual : (${resultado.toStringAsPrecision(3)})\n\nVale a pena abastecer com Gasolina" ;
} else {
_infoText="Percentual : (${resultado.toStringAsPrecision(3)})\n\nVale a pena abastecer com Álcool" ;
}
});
}
|
Aqui cabe ressaltar o uso do setState() para poder atualizar o estado dos widgets que sofreram alteração e isso ser refetido na interface do usuário atualizando a tela. No cálculo usamos toStringAsPrecision(3) para definir uma precisão de 3 casas decimais após a vírgula.
Note que obtemos os valores informados pelo usuário usando os controllers - gasolinaController e alcoolController.
A aplicação pode ser melhorada em diversos aspectos como a validação e outros detalhes.
Pegue os arquivos do projeto aqui: flutter_combustivel.zip
"Sujeitai-vos, pois, a Deus, resisti ao diabo, e ele fugirá de vós." Tiago 4:7
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
Flutter - Lista Básica - Macoratti
Flutter - Apresentando o widget MaterialApp - Macoratti
Flutter - Apresentando Flutter Studio - Macoratti
Flutter - Apresentando Widgets - Macoratti
Flutter - Criando uma tela de login - Macoratti