Mobile

16 mai, 2019

Flutter – Criando uma tela de login – Parte 02

Publicidade

No artigo de hoje seguiremos com a criação da 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.

Abriremos o arquivo login.dart, que foi criado na pasta widgets e criaremos um StatefullWidget chamado Login.

No Visual Studio Code basta digitar stf e, a seguir selecionar 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 usado 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')
          ],),)    
    );
  }
}

Já temos o texto centralizado e empilhado, e nosso layout já está começando a tomar forma. Agora perceba que os textos estão muito próximos à borda da tela. Incluiremos um preenchimento ou padding a partir do body envolvendo o widget Center.

Para fazer isso, selecione o widget Center, e a seguir clique no í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 de 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.

Substituiremos 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 usaremos as seguintes:

  • autofocus: define o autofoco no campo
  • keyboardType: permite escolher o tipo de teclado
  • obscureText: oculta o texto que está sendo editado (usado em senhas)
  • style: permite aplicar um estilo ao texto

Vamos então definir o TextField no lugar de Text, conforme o código 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. Esse widget terá um child Text onde definiremos 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. Esse 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 widget Divider.

O 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, incluiremos 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,
                ),
              ),
            ],
         ),
        ),
      )
   );
  }
}

Concluímos, assim, a definição do nosso layout da tela de login.

Pegue o código do arquivo main.dart e dos widgets no link a seguir:

Aguarde mais artigos sobre Flutter.