Drag and Drop functionality in Flutter allows users to interact with UI elements by dragging them across the screen and dropping them in a desired location. Flutter provides the Draggable, DragTarget, and LongPressDraggable widgets to implement these interactions. Here’s a simple guide to implementing drag and drop in Flutter:

Create a Draggable Widget

This widget can be dragged across the screen.

Create a DragTarget Widget 

This widget acts as a target where the draggable can be dropped.

Explanation

  1. Draggable Widget Properties
    • Draggable<T>: A widget that can be dragged. The generic type <T> specifies the type of data being dragged.
    • data: The data that is being dragged. In this case, it’s a Color.
    • child: The widget to display when not being dragged.
    • feedback: The widget to display while being dragged.
    • childWhenDragging: The widget to display in place of the child when it is being dragged.
  2. DragTarget Widget Properties
    • DragTarget<T>: A widget that accepts data of type T.
    • onAccept: A callback that is called when the draggable is dropped onto this target.
    • builder: A builder function that provides the context, the list of data accepted, and the list of data rejected during the drag-and-drop operation.

Advanced Features

We can further customize the drag and drop interaction by using additional callbacks and properties provided by Draggable and DragTarget, such as:

  • onDragStarted: A widget will call this method once dragging the widget 
  • onDragUpdate: A widget is giving the DragUpdateDetails class object.
  • onDragCompleted: A widget will call this method on a successful drop widget in the drag target view.
  • onDraggableCanceled: A widget will call this method on an unsuccessful drop widget in the drag target view.
  • onWillAccept: A drag target widget will check and verify data for accepting or rejecting a draggable object in its drop region.

These allow us to manage the drag and drop states more precisely, providing a richer user experience.

Code Example

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('Drag and Drop Example')),
        body: DragDropDemo(),
      ),
    );
  }
}

class DragDropDemo extends StatefulWidget {
  @override
  _DragDropDemoState createState() => _DragDropDemoState();
}

class _DragDropDemoState extends State<DragDropDemo> {
  Color caughtColor = Colors.grey;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Draggable<Color>(
            data: Colors.blue,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
              child: Center(
                child: Text(
                  'Drag me',
                  style: TextStyle(color: Colors.white, fontSize: 18),
                ),
              ),
            ),
            feedback: Material(
              color: Colors.transparent,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue.withOpacity(0.5),
                child: Center(
                  child: Text(
                    'Dragging',
                    style: TextStyle(color: Colors.white, fontSize: 18),
                  ),
                ),
              ),
            ),
            
            childWhenDragging: Container(
              width: 100,
              height: 100,
              color: Colors.grey,
              child: Center(
                child: Text(
                  'Original',
                  style: TextStyle(color: Colors.white, fontSize: 18),
                ),
              ),
            ),
          ),
          DragTarget<Color>(
            onAccept: (color) {
              setState(() {
                caughtColor = color;
              });
            },
            builder: (context, accepted, rejected) {
              return Container(
                width: 200,
                height: 200,
                color: accepted.isEmpty ? caughtColor : Colors.grey.shade200,
                child: Center(
                  child: Text(
                    'Drop here',
                    style: TextStyle(color: Colors.black, fontSize: 18),
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

Output

You may also like

Leave a Reply