Flutter - Apresentando e usando o Widget Dismissible


No artigo de hoje veremos o widget Dismissible e como podemos usá-lo na prática.

O que é o Flutter ?

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

Apresentando o widget Dismissible

O Widget Dismissible é um widget que podemos usar para implementar o padrão 'deslizar/arrastar para descartar'. Esse padrão é muito comum no mundo mobile sendo muito usado quando o usuário arrasta um item para a direita ou esquerda com o objetivo de descartá-lo.

Para implementar essa funcionalidade no Flutter usando o widget Dismissible podemos fazer assim:

  1. Criar um lista de itens;
  2. Envolver cada item com um widget Dismissible;
  3. Implementar o arrastar para descartar;

Vejamos isso funcionando na prática.

Implementando Dismissible - Criando o projeto

Crie um novo projeto Flutter no VS Code e no arquivo main.dart na pasta lib vamos iniciar definindo o código padrão usando o MaterialApp onde estamos desabilitando a label de Debug e definindo o Widget MyApp() no parâmetro home que é a porta de entrada da aplicação:

import 'package:flutter/material.dart';
void main(){
  runApp(  MaterialApp(
    debugShowCheckedModeBanner: false,
    home:   MyApp(),
  ));
}

A seguir vamos criar o StatefulWidget MyApp() onde usamos o Scaffold definindo a AppBar, o título centralizado, a cor de fundo azul e em body definimos o método _body retornando um Container, mas a seguir vamos criar um ListView:

Nota: Aqui também poderíamos ter criado um StatelessWidget.

import 'package:flutter/material.dart';
void main(){
  runApp(  MaterialApp(
    debugShowCheckedModeBanner: false,
    home:   MyApp(),
  ));
}
class MyApp extends StatefulWidget {
  @override
  _State createState() =>   _State();
}
class _State extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    return   Scaffold(
      appBar: AppBar(
        title: Text('Usando Dismissible'),
        centerTitle: true,
        backgroundColor: Colors.blue,
      ),
      body: _body(),
    );
  }
  _body(){
    return Container();
  }
}

Implementando Dismissible - Criando o ListView

A seguir na classe _State vamos criar um array chamado estados contendo o nome de alguns estados brasileiros que iremos usar para exibir no ListView.

Depois no método _body() vamos criar um ListView usando o construtor builder para exibir os itens do array:

 List estados = ['São Paulo','Minas Gerais','Paraná',
  'Rio Grande do Sul','Rio de Janeiro','Espirito Santo',
  'Santa Catarina','Bahia','Brasilia','Mato Grosso',
  'Mato Grosso do Sul','Amazonas','Pernambuco','Ceará'
 ];
  _body(){
    return ListView.builder(
        itemCount: estados.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(estados[index]),
          );
        },
      );
  }
 

Temos assim uma lista de itens exibidos no ListViews.

Implementando Dismissible - Envolvendo cada item com um Dismissible

Agora vamos dar aos usuário a capacidade de deslizar um item da lista usando o widget Dismissible.

Depois que o usuário tiver retirado o item, vamos remover o item da lista exibindo-o em um snackbar.

Em uma aplicação real, pode ser necessário executar uma lógica mais complexa, como remover o item de um serviço da web, de um banco de dados, do sistema de arquivos, etc.

Vamos atualizar a função itemBuilder() para retornar um widget Dismissible e usando este widget vamos definir uma key para identificar cada widget de forma única e usar a função onDismissed() para remover o item da lista.

Observe que usamos setState() para poder atualizar a interface e a seguir usamos o Scaffold.of para exibir um snackbar com a mensagem do item removido.

 _body(){
    return ListView.builder(
        itemCount: estados.length,
        itemBuilder: (context, index) {          
         final item = estados[index];
            return Dismissible(
              // Cada Dismissible deve conter uma Key. 
              // As Keys permitem ao Flutter 
              // identificar o widget de forma única
              key: Key(item),
              // Fornecemos uma função que diz ao app
              // o que fazer depois que o item for arrastado
              onDismissed: (direction) {
                // Remove o item da fonte de dados
                setState(() {
                  estados.removeAt(index);
                });
                // Exibe o snackbar
                Scaffold
                    .of(context)
                    .showSnackBar(
                      SnackBar(
                        content: 
                        Text(
                          "$item foi removido"),
                        ),
                     );
              },
              // Exibe uma cor vermelha de fundo 
              // quando o item for arrastado
              background: Container(color: Colors.red),
              child: ListTile(title: Text('$item')),
            );
        },
      );
  }

Implementamos também uma cor de fundo vermelha no Container para exibir quando o item for arrastado.

Note que como estamos trabalhando apenas na memória os itens retornarão quando a aplicação for reiniciada.

Vamos agora incluir um ícone de uma lixeira no Container de forma que quando o item for arrastado ele seja exibido para ilustrar a remoção do item:

 _body(){
    return ListView.builder(
        itemCount: estados.length,
        itemBuilder: (context, index) {          
         final item = estados[index];
            return Dismissible(
              // Cada Dismissible deve conter uma Key. 
              // As Keys permite ao Flutter 
              // identificar o widget de forma única
              key: Key(item),
              // Fornecemos uma função que diz ao app
              // o que fazer depois que o item for arrastado
              onDismissed: (direction) {
                // Remove o item da fonte de dados
                setState(() {
                  estados.removeAt(index);
                });
                // Exibe o snackbar
                Scaffold
                    .of(context)
                    .showSnackBar(
                      SnackBar(
                        content: 
                        Text(
                          "$item foi removido"),
                        ),
                     );
              },
              // Exibe uma cor vermelha de fundo 
              // quando o item for arrastado
              background: Container(
                color: Colors.red,
                child: Align( 
                   alignment: Alignment(-0.9, 0), 
                   child: Icon(Icons.delete, color: Colors.white),
                 ),
                ),
              child: ListTile(title: Text('$item')),
            );
        },
      );
  }

No código destacado em azul incluimos um widget Align para alinhar o ícone à esquerda e a seguir criamos o ícone na cor branca usando o widget Icon.

Pegue o código dos arquivos dart usados no projeto aqui:  main_dismissible.dart

"O Senhor é o meu rochedo, e o meu lugar forte, e o meu libertador; o meu Deus, a minha fortaleza, em quem confio; o meu escudo, a força da minha salvação, e o meu alto refúgio."
Salmos 18:2

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