Como Usar DragTarget e Draggable no Flutter para Interações de Arrastar e Soltar

Introdução

No Flutter, os widgets DragTarget e Draggable permitem criar interações dinâmicas e intuitivas de arrastar e soltar. Eles são amplamente utilizados em interfaces de usuário que requerem manipulação direta de elementos, como jogos, editores de design e organizadores visuais.

Neste tutorial, vamos explorar como usar Draggable e DragTarget para criar uma interação completa de arrastar e soltar no Flutter.

1. Criando um Draggable Básico

O widget Draggable permite que os usuários arrastem elementos na tela. Aqui está um exemplo simples:


import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Draggable Example')),
        body: const Center(
          child: DraggableExample(),
        ),
      ),
    );
  }
}

class DraggableExample extends StatelessWidget {
  const DraggableExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Draggable(
      data: 'Flutter',
      feedback: Material(
        color: Colors.blue,
        child: const Padding(
          padding: EdgeInsets.all(8.0),
          child: Text(
            'Arrastando!',
            style: TextStyle(color: Colors.white, fontSize: 16),
          ),
        ),
      ),
      childWhenDragging: const Opacity(
        opacity: 0.5,
        child: FlutterLogo(size: 100),
      ),
      child: const FlutterLogo(size: 100),
    );
  }
}

2. Adicionando um DragTarget

O widget DragTarget é onde os itens arrastáveis podem ser soltos. Ele permite executar ações baseadas nos dados recebidos do Draggable:


class DragTargetExample extends StatefulWidget {
  @override
  _DragTargetExampleState createState() => _DragTargetExampleState();
}

class _DragTargetExampleState extends State {
  String _receivedData = '';

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        DragTarget(
          onAccept: (data) {
            setState(() {
              _receivedData = data;
            });
          },
          builder: (context, candidateData, rejectedData) {
            return Container(
              height: 150,
              width: 150,
              color: candidateData.isNotEmpty ? Colors.green : Colors.grey,
              child: Center(
                child: Text(
                  _receivedData.isEmpty ? 'Solte aqui!' : _receivedData,
                  style: const TextStyle(color: Colors.white, fontSize: 16),
                ),
              ),
            );
          },
        ),
        const SizedBox(height: 20),
        Draggable(
          data: 'Flutter',
          feedback: Material(
            color: Colors.blue,
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Text(
                'Arrastando!',
                style: TextStyle(color: Colors.white, fontSize: 16),
              ),
            ),
          ),
          child: const FlutterLogo(size: 100),
        ),
      ],
    );
  }
}

3. Estilizando e Adicionando Feedback Visual

Para melhorar a experiência do usuário, adicione animações e feedback visual ao arrastar:


class StyledDragTarget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        DragTarget(
          onWillAccept: (data) {
            // Mudar a cor ao passar por cima
            return true;
          },
          onAccept: (data) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('Você soltou: $data')),
            );
          },
          builder: (context, candidateData, rejectedData) {
            return AnimatedContainer(
              duration: const Duration(milliseconds: 300),
              height: 150,
              width: 150,
              color: candidateData.isNotEmpty ? Colors.green : Colors.grey,
              child: const Center(
                child: Text(
                  'Solte aqui!',
                  style: TextStyle(color: Colors.white, fontSize: 16),
                ),
              ),
            );
          },
        ),
        const SizedBox(height: 20),
        Draggable(
          data: 'Flutter Logo',
          feedback: Material(
            color: Colors.orange,
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Text(
                'Arrastando...',
                style: TextStyle(color: Colors.white, fontSize: 16),
              ),
            ),
          ),
          child: const FlutterLogo(size: 100),
        ),
      ],
    );
  }
}

4. Boas Práticas

  • Use animações para fornecer feedback visual claro ao usuário.
  • Adicione sons ou vibrações para melhorar a interação.
  • Valide os dados recebidos no DragTarget para evitar erros.

Publicar comentário