Dismissível no Flutter

Tempo de leitura: 6 minutes

No Flutter, supondo que você queira criar um widget que possa ser dispensado, você pode encapsular o widget como filho de Dismissible. Um Widget descartável no Flutter é normalmente usado para agrupar cada item da lista com o objetivo de que ele seja dispensado, seja na direção horizontal ou vertical.

Este blog irá explorar o Dismissible In Flutter. Percebemos como executar um programa de demonstração. Descobriremos como utilizar o widget, incluindo como mostrar a caixa de diálogo de confirmação, definir planos de fundo que serão exibidos quando a criança estiver sendo dispensada e definir direções de dispensa em seus aplicativos Flutter.

 

Introdução:

Um widget que pode ser descartado arrastando na direção demonstrada. Arrastar ou arremessar este widget no DismissDirection faz com que o filho deslize para fora da vista.

Módulo de Demonstração ::

Este vídeo de demonstração mostra como usar o dispensável em um flutter e mostra como um dispensável funcionará em seus aplicativos flutter. Mostraremos um usuário arrastando ou dedilhado dispensando um widget. Ele será exibido em seus dispositivos.

 

Construtor:

Para utilizar Dismissible, você precisa chamar o construtor abaixo:

Você é obrigado a passar a Key (Key) e child (Widget). A chave acaba sendo vital, pois o widget pode ser retirado da lista de widgets. Se houver widgets dispensáveis diferentes, certifique-se de que cada um tenha uma key exclusiva.

const Dismissible({
  required Key key,
  required this.child,
  this.background,
  this.secondaryBackground,
  this.confirmDismiss,
  this.onResize,
  this.onUpdate,
  this.onDismissed,
  this.direction = DismissDirection.horizontal,
  this.resizeDuration = const Duration(milliseconds: 300),
  this.dismissThresholds = const <DismissDirection, double>{},
  this.movementDuration = const Duration(milliseconds: 200),
  this.crossAxisEndOffset = 0.0,
  this.dragStartBehavior = DragStartBehavior.start,
  this.behavior = HitTestBehavior.opaque,
})

Esteja atento para não envolver o índice como uma chave, pois descartar um widget pode alterar o índice de diferentes widgets. A segunda propriedade necessária é um child onde você deseja passar o widget que pode ser dispensado.

Outra propriedade significativa é onDismissed. É uma função de retorno de chamada que tolera um limite do tipo DismissDirection. Dentro, você pode caracterizar o que fazer depois que o widget for descartado. Por exemplo, você pode eliminar o widget da lista.

Propriedades:

Existem algumas propriedades de Dismissible são:

  • key — Esta propriedade é usada para controlar se deve ser substituída.
  • child — Esta propriedade é usada abaixo deste widget na árvore.
  • background — Esta propriedade é usada para empilhar atrás do child. Se o SecondBackground estiver definido, ele só é mostrado quando o child está sendo arrastada para baixo ou para a direita.
  • secondBackground — Esta propriedade é usada para empilhar atrás do child. Só é mostrado quando o child está sendo arrastada para cima ou para a esquerda.
  • confirmDismiss — Esta propriedade é usada para permitir que o aplicativo confirme ou vete uma dispensa pendente.
  • onResize — Esta propriedade é usada para o retorno de chamada que será chamado quando o widget mudar de tamanho.
  • onDismissed — Esta propriedade é usada para o retorno de chamada que será chamado quando o widget for descartado.
  • direction — Esta propriedade é usada para a direção na qual o widget pode ser dispensado. O padrão é DismissDirection.horizontal.
  • resizeDuration — Esta propriedade é usada para a quantidade de tempo que o widget gastará contraindo antes de onDismissed ser chamado. O padrão é const Duration(milissegundos: 300).
  • dispenseThresholds — Esta propriedade é usada para definir o limite de deslocamento que o item deve ser arrastado para ser considerado descartado. O padrão é const <DismissDirection, double>{}.
  • motionDuration — Esta propriedade é usada para a duração para descartar ou voltar à posição original se não for descartada. O padrão é const Duration(milissegundos: 200).
  • crossAxisEndOffset — Esta propriedade é usada para o deslocamento final no eixo principal depois que o cartão é dispensado. O padrão é 0,0.
  • dragStartBehavior — Esta propriedade é usada para saber como o comportamento de arrastar é tratado. O padrão é DragStartBehavior.start.

 

Como implementar o código no arquivo dart:

Você precisa implementá-lo em seu código, respectivamente:

Crie um novo arquivo dart chamado main.dart dentro da pasta lib.

Faremos um ListView básico onde a coisa pode ser dispensada. O ListView é feito utilizando os valores que o acompanham.

List<String> items = [
  "Assistir",
  "Jeans",
  "Camisa",
  "Camiseta",
  "Xícara",
  "Sapato",
  "Boné",
  "Shorts",
  "Calça",
  "Mais baixo",
];

Aqui está o código para construir o ListView. O itemBuilder, que é utilizado para construir a lista de itens, retorna um Dismissible. Não obstante os argumentos necessários (key e chield), um retorno de chamada onDismissed é passado adicionalmente. O modelo abaixo informa a melhor maneira de definir várias ações para cada direção.

ListView.builder(
    itemCount: items.length,
    padding: const EdgeInsets.symmetric(vertical: 16),
    itemBuilder: (BuildContext context, index) {
      return Dismissible(
        key: Key('item ${items[index]}'),
        onDismissed: (DismissDirection direction) {
          if (direction == DismissDirection.startToEnd) {
            print("Adicionar presente ao carrinho");
          } else {
            print('Mover para lixeira');
          }
 
          setState(() {
            items.removeAt(index);
          });
        },
        child: ListTile(
                leading: const Icon(
                  Icons.card_giftcard_rounded,
                  color: Colors.black,
                ),
                title: Text(
                  items[index],
                  style: TextStyle(
                      color: Colors.black.withOpacity(.6), fontSize: 18),
                ),
                subtitle: Text(
                  "Este presente é para você",
                  style: TextStyle(color: Colors.green.withOpacity(.6)),
                ),
              ),
      );
    }
  ),

Quando executamos o aplicativo, devemos obter a saída da tela como a captura de tela abaixo.

 

Mostrando Confirmação

Dismissible é frequentemente utilizado para excluir uma atividade. Se você acha que a atividade executada é crítica e não pode ser dispersada, é mais inteligente mostrar a confirmação antes que a atividade seja caracterizada dentro de onDismissed é executada.

Você pode fazer isso passando confirmDismissCallback para o construtor. Um retorno de chamada reconhece um parâmetro do tipo DismissDirection e retorna Future<bool>. O modelo abaixo mostra um AlertDialog onde o cliente pode confirmar a exclusão do item ou cancelar a ação.

confirmDismiss: (DismissDirection direction) async {
    return await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("Adicionar presente ao carrinho"),
          content: const Text("Tem certeza que deseja adicionar este presente em seu carrinho?"),
          actions: <Widget>[
            ElevatedButton(
                onPressed: () => Navigator.of(context).pop(true),
                 child: const Text("Sim")),
            ElevatedButton(
                onPressed: () => Navigator.of(context).pop(false),
                child: const Text("Não"),
             ),
          ],
        );
      },
    );
  }

 

Definindo planos de fundo

A direção de dispensa padrão é horizontal. Você pode deslizar para a direita ou para a esquerda. Deslizar para a esquerda ou para a direita pode resultar em uma ação alternativa dependendo do que você caracteriza no retorno de chamada onDismissed. Várias ações, mas o Flutter também permite que você defina vários widgets que serão exibidos quando o child estiver sendo dispensada.

Utilize o fundo para caracterizar o widget a ser mostrado quando o child for deslizado para a direita e o secondaryBackground para o widget quando o child for deslizado para a esquerda. Supondo que você acabou de definir o plano de fundo, ele será utilizado para as duas direções.

background: Container(
  color: Colors.blue,
  child: Padding(
    padding: const EdgeInsets.all(15),
    child: Row(
      children: const [
        Icon(Icons.favorite, color: Colors.red),
        SizedBox(
          width: 8.0,
        ),
        Text('Mover para favoritos',
            style: TextStyle(color: Colors.white)),
      ],
    ),
  ),
),
secondaryBackground: Container(
  color: Colors.red,
  child: Padding(
    padding: const EdgeInsets.all(15),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.end,
      children: const [
        Icon(Icons.delete, color: Colors.white),
        SizedBox(
          width: 8.0,
        ),
        Text('Mover para lixeira',
            style: TextStyle(color: Colors.white)),
      ],
    ),
  ),
),

Quando executamos o aplicativo, devemos obter a saída da tela como a captura de tela abaixo.

 

Code File:

import 'package:flutter/material.dart';

class DismissibleDemo extends StatefulWidget {
  const DismissibleDemo({Key? key}) : super(key: key);

  @override
  State<DismissibleDemo> createState() => _DismissibleDemoState();
}

class _DismissibleDemoState extends State<DismissibleDemo> {
  List<String> items = [
    "Assistir",
    "Jeans",
    "Camisa",
    "Camiseta",
    "Xícara",
    "Sapato",
    "Boné",
    "Shorts",
    "Calça",
    "Mais baixo",
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.blue.shade400,
          centerTitle: true,
          automaticallyImplyLeading: false,
          title: const Text("Demonstração Flutter Dismissible"),
        ),
        body: ListView.builder(
          itemCount: items.length,
          padding: const EdgeInsets.symmetric(vertical: 16),
          itemBuilder: (BuildContext context, int index) {
            return Dismissible(
              background: Container(
                color: Colors.blue,
                child: const Padding(
                  padding: EdgeInsets.all(15),
                  child: Row(
                    children: [
                      Icon(Icons.favorite, color: Colors.red),
                      SizedBox(
                        width: 8.0,
                      ),
                      Text('Mover para favoritos',
                          style: TextStyle(color: Colors.white)),
                    ],
                  ),
                ),
              ),
              secondaryBackground: Container(
                color: Colors.red,
                child: const Padding(
                  padding: EdgeInsets.all(15),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      Icon(Icons.delete, color: Colors.white),
                      SizedBox(
                        width: 8.0,
                      ),
                      Text('Mover para lixeira',
                          style: TextStyle(color: Colors.white)),
                    ],
                  ),
                ),
              ),
              key: ValueKey<String>(items[index]),
              onDismissed: (DismissDirection direction) {
                setState(() {
                  items.removeAt(index);
                });
              },
              confirmDismiss: (DismissDirection direction) async {
                if (direction == DismissDirection.startToEnd) {
                  return await showDialog(
                    context: context,
                    builder: (BuildContext context) {
                      return AlertDialog(
                        title: const Text("Adicionar presente ao carrinho"),
                        content: const Text(
                            "Tem certeza que deseja adicionar este presente em seu carrinho"),
                        actions: <Widget>[
                          ElevatedButton(
                              onPressed: () => Navigator.of(context).pop(true),
                              child: const Text("Sim")),
                          ElevatedButton(
                            onPressed: () => Navigator.of(context).pop(false),
                            child: const Text("Não"),
                          ),
                        ],
                      );
                    },
                  );
                } else {
                  return await showDialog(
                    context: context,
                    builder: (BuildContext context) {
                      return AlertDialog(
                        title: const Text("Remover presente"),
                        content: const Text(
                            "Tem certeza de que deseja remover este item de presente?"),
                        actions: <Widget>[
                          ElevatedButton(
                              onPressed: () => Navigator.of(context).pop(true),
                              child: const Text("Sim")),
                          ElevatedButton(
                            onPressed: () => Navigator.of(context).pop(false),
                            child: const Text("Não"),
                          ),
                        ],
                      );
                    },
                  );
                }
              },
              child: ListTile(
                leading: const Icon(
                  Icons.card_giftcard_rounded,
                  color: Colors.black,
                ),
                title: Text(
                  items[index],
                  style: TextStyle(
                      color: Colors.black.withOpacity(.6), fontSize: 18),
                ),
                subtitle: Text(
                  "Este presente é para você",
                  style: TextStyle(color: Colors.green.withOpacity(.6)),
                ),
              ),
            );
          },
        ));
  }
}

Github:

 

Conclusão:

No artigo, expliquei a estrutura básica Dismissível rapidamente; você pode modificar este código de acordo com sua escolha. Esta foi uma pequena introdução à Interação do usuário descartável da minha parte, e está funcionando usando o Flutter.

Espero que este blog forneça a você informações suficientes sobre como experimentar o descartável em seus projetos de vibração. Mostraremos o que é a Introdução e quais são a construção e as propriedades do Dismissible e faremos um programa de demonstração para trabalhar com o Dismissible em seus aplicativos flutter. Então, por favor, tente.

Não deixe de conhecer meus Ebooks de Flutter/Dart