Flutter - Criando uma tela de login - II


No artigo de hoje vamos continuar a criar a tela de Login no Flutter.

Continuando a primeira parte do artigo vamos definir o widget Login que vai ser um widget com estado ou seja vai estender de StatefullWidget.

Um StatefulWidget é um widget que possui estado mutável. Estado é a informação que pode ser lida de forma síncrona quando o widget é construído e que pode mudar durante o tempo de vida do widget.

É responsabilidade do implementador do widget garantir que o State seja notificado imediatamente quando esse estado for alterado, usando State.setState.

Vamos abrir o arquivo login.dart que foi criado na pasta widgets e vamos criar um StatefullWidget chamado Login.

No Visual Studio Code basta digitar 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 Login e você deverá ver o código abaixo:

Precisamos importar o pacote 'flutter/material.dart' :

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:

Para executar, no VS Code, no modo Debug, pressione F5.

Na janela de comandos (cmd), posicione-se na pasta do projeto e digite o comando:  Flutter run

O resultado pode ser visto abaixo.

Vemos apenas uma tela preta pois precisamos definir o widget de login.

Definindo o layout do login

Vamos iniciar a definição do layout da tela de login.

Fazendo um esboço do nosso layout temos que ter :

- Layout centralizado com cor de fundo
- Dois widgets para entrada do usuário um sobre o outro com textos;
- No primeiro é exibido o teclado numérico;
- No segundo é exibido o teclado alfanumérico;
- Um Button com bordas arredondas e um texto;

Assim, para começar, teremos que :

a- Substituir o widget Container pelo Scaffold
b- Definir o backgroundColor com a cor desejada
c- Definir o body do Scaffold usando o widget Center para centralizar o texto
d- Definir um child Column do body para empilhar o texto usando e definir o alinhamento como centralizado

Alterando o código conforme abaixo veremos o resultado exibido no emulador conforme a figura:

import 'package:flutter/material.dart';
class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Telefone do usuário'),
            Text('Senha do usuário')
          ],),)    
    );
  }
}

Ja temos o texto centralizado e empilhado e nosso layout já esta começando a tomar forma.

Agora perceba que os textos estão muito próximos à borda da tela. Vamos incluir um preenchimento ou padding a partir do body envolvendo o widget Center.

Para fazer isso selecione o widget Center e a seguir clique ícone e selecione : Add padding

Será incluído um widget Padding com a constante EdgeInsets.all(8.0) que insere preenchimentos em todos os lados com um valor de 8. Vamos alterar esse valor para 10 e na figura abaixo já vemos o resultado no emulador:

import 'package:flutter/material.dart';
class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Telefone do usuário'),
              Text('Senha do usuário')
            ],),),
      ) //padding
      
    );
  }
}

Lembre-se que os textos devem apresentar um teclado ao usuário, onde o primeiro vai apresentar um teclado numérico e o segundo um teclado alfanumérico.

Temos que usar um widget com recursos para receber a entrada do usuário e exibir o teclado numérico. O widget Text que estamos usando é imutável.

Vamos substituir o Text pelo o widget TextField que é um campo de texto do material design. Esse widget é um campo de texto que permite que o usuário insira texto, seja com o teclado do hardware ou com um teclado na tela.

O TextField chama o callback onChanged sempre que o usuário altera o texto no campo. Se o usuário indicar que está pronto para digitar no campo (por exemplo, pressionando um botão no teclado virtual), o campo de texto chama o callback onSubmitted.

Além disso esse widget possui diversas propriedades dentre as quais iremos usar :

Vamos então definir o TextField no lugar de Text conforme o código mostrado a seguir:

import 'package:flutter/material.dart';
class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
               TextField(
                autofocus: true,
                keyboardType: TextInputType.number,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Telefone do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
           ),  //TextField
              TextField(
                autofocus: true,
                obscureText: true,
                keyboardType: TextInputType.text,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Senha do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
              ),//TextField
            ],
         ),
        ),
      )     
    );
  }
}

Note que o texto exibido acima do campo de texto é obtido usando o decoration: InputDecoration onde definimos o texto e o estilo do texto.

Agora só falta incluir o botão com bordas arredondadas um texto e uma cor vermelha.

Para isso vamos incluir no children do widget Column um RaisedButton e usar a propriedade shape para definir os cantos arredondados. Este widget terá um child Text onde vamos definir o texto exibido no botão.

import 'package:flutter/material.dart';
class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
               TextField(
                autofocus: true,
                keyboardType: TextInputType.number,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Telefone do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
           ),
              TextField(
                autofocus: true,
                obscureText: true,
                keyboardType: TextInputType.text,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Senha do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
              ),
              ButtonTheme(
                height: 60.0,
                child: RaisedButton(
                  onPressed: () => { print("pressionei o botão"), },
                  shape: new RoundedRectangleBorder(borderRadius:
 new BorderRadius.circular(30.0)),
                  child: Text(
                    "Enviar",
                    style: TextStyle(color: Colors.white, fontSize: 30),
                  ), //Text
                  color:Colors.red,
                ),//RaisedButton
              ),//ButtonTheme
            ],
         ),
        ),
      )     
    );
  }
}

Tivemos que definir o callback onPressed onde estamos imprimindo o texto 'pressionei o botão' no console.

Além disso, para poder alterar o tamanho do botão estamos envolvendo o RaisedButton com o widget ButtonTheme e definindo a propriedade height com o valor 60.0. Este widget permite configurar a geometria dos botões.

Agora perceba que o botão ficou muito junto do campo texto. Podemos separar um pouco os elementos do layout que estão empilhados no widget Column usando o wdiget Divider.

A widget Divider representa uma linha horizontal de um pixel de um dispositivo, com preenchimento em ambos os lados. ( Na linguagem material design, isso representa um divisor.)

Assim vamos incluir um Divider() para separar os campos e também o botão.

O código final ficou assim:

import 'package:flutter/material.dart';
class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amberAccent,
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
               TextField(
                autofocus: true,
                keyboardType: TextInputType.number,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Telefone do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
           ),
              Divider(),
              TextField(
                autofocus: true,
                obscureText: true,
                keyboardType: TextInputType.text,
                style: TextStyle(color: Colors.blue, fontSize: 30),
                decoration: InputDecoration(
                  labelText:"Senha do usuário",
                  labelStyle: TextStyle(color: Colors.black),
                )
              ),
              Divider(),
              ButtonTheme(
                height: 60.0,
                child: RaisedButton(
                  onPressed: () => {
                    print("pressionei o botão"),
                  },
                  shape: new RoundedRectangleBorder(borderRadius: 
new BorderRadius.circular(30.0)),
                  child: Text(
                    "Enviar",
                    style: TextStyle(color: Colors.white, fontSize: 30),
                  ),
                  color:Colors.red,
                ),
              ),
            ],
         ),
        ),
      )
   );
  }
}

Concluimos assim a definição do nosso layout da tela de login.

Pegue o código do arquivo main.dart e dos widgets aqui : flutter_tela_login.zip

Aguarde mais artigos sobre Flutter.

"E, quanto fizerdes por palavras ou por obras, fazei tudo em nome do Senhor Jesus, dando por ele graças a Deus Pai."
Colossenses 3:17

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:


José Carlos Macoratti