Exploring Drag And Drop Functionality In Flutter

Drag and drop functionality is a key aspect of modern user interfaces, allowing users to interact with digital content in an intuitive and engaging manner. In Flutter, implementing drag and drop features is made easy with the Draggable and DragTarget widgets. Let’s dive into these widgets, their functionalities, and the drag and drop process in Flutter applications.

iDigisol web | Drag and Drop Flutter ad

Understanding Draggable Widget

The Draggable widget in Flutter enables the creation of draggable items within the user interface. It offers three primary functionalities:

1. Child Widget

The child parameter of the Draggable widget defines the widget that will serve as the draggable item. This widget can be any Flutter widget, such as Container, Image, Text, etc.

2. Feedback Widget

The feedback parameter specifies the widget that provides a visual representation of the item being dragged. Typically, it’s a duplicate of the child widget but can be customized to offer visual feedback during drag.

3. Data

With the data parameter, you can attach any relevant data to the draggable item. This data can be accessed when the item is dropped onto a DragTarget, allowing for further processing or updating the application state.

Exploring DragTarget Widget

The DragTarget widget defines areas in the UI where draggable items can be dropped. It offers the following functionalities:

1. Builder Function

The builder parameter of DragTarget is a callback function responsible for defining the widget tree representing the drop target. It typically returns a container or any other widget that visually signifies the drop zone.

2. OnWillAccept Function

The onWillAccept callback function is invoked when a draggable item is dragged over the DragTarget. It determines whether the DragTarget will accept the dragged item based on the returned boolean value, allowing for custom acceptance logic implementation.

onWillAccept: (data) => true,

3. OnAccept Function

Upon dropping a draggable item onto the DragTarget, the onAccept callback function is triggered. This function enables you to define actions to be performed when the item is successfully dropped, such as updating state or processing the dropped item’s data.

onAccept: (data) {
setState(() {

});
},

The Drag And Drop Process

The drag and drop process can be divided into three stages:

1. Before Drag

This stage represents the initial state of the UI before the user starts dragging an item. Draggable items are displayed in their initial positions, and the drop targets are empty.

In code this would be the equivalent.

Draggable<Container>(child: item)

2. During Drag

During this stage, the user is actively dragging an item. The feedback widget provided by the Draggable widget is displayed, offering visual feedback about the dragged item’s position.

In code this would be the equivalent.

Draggable<Container>(
data: item,
//onDragStarted: , This is an option if you would like to happen while drag has started. 
feedback: item, 
//childWhenDragging: Container(), This is an option if you would like something to happen to the child while dragging.
child: item,
)).toList(),

3. After Drag

After dropping an item onto a drop target, the onAccept function of the DragTarget is invoked. This stage allows for actions to be taken based on the dropped item, such as updating UI state or processing the dropped item’s data.

Draggable<Container>(
data: item,
feedback: item,
//onDragEnd: (){}, //IF you want something to happen when you are at the end of the drag. 
//onDragCompleted: (){}, //If you would like something to happen when drag is completed.
//onDraggableCanceled: ,//If you would like something to happen when cancelled. 
//childWhenDragging: Container(),
child: item,
)).toList(),

Integrating Code Example

Let’s integrate the provided code example to demonstrate how to implement drag and drop functionality in a Flutter application:

import 'package:flutter/material.dart'; 
void main() { 
  runApp(MyApp()); 

} 

class MyApp extends StatelessWidget { 
@override Widget build(BuildContext context) { 
  return MaterialApp( 
         home: DragAndDropScreen(), 
         ); 
      }
 } 

class DragAndDropScreen extends StatefulWidget { 
@override _DragAndDropScreenState createState() => _DragAndDropScreenState(); } 

class _DragAndDropScreenState extends State<DragAndDropScreen> { 
     List<Container> containers = []; 
  List<Container> draggableItems = [];
  @override void initState() { 
    super.initState(); 
    draggableItems = [ 
       _buildDraggableContainer(Colors.red),
       _buildDraggableContainer(Colors.blue),
       _buildDraggableContainer(Colors.green),
       _buildDraggableContainer(Colors.yellow),
       _buildDraggableContainer(Colors.orange),          ]; } 
   Container _buildDraggableContainer(Color color) { 
    return Container( 
             width: 100, 
             height: 100, 
             color: color, 
             child: const Center( 
                            child: Text('Drag Me', style: TextStyle(color: Colors.white)),
                           ), 
           ); 
} 
@override Widget build(BuildContext context) { 
return Scaffold( 
         appBar: AppBar( 
         title: const Text('Drag and Drop Example'),
       ),                  body: Row( children: [                     Expanded( 
                    child: DragTarget<Container>( 
                      builder: (context, candidateData, rejectedData) { 
                        return Container( 
                           color: Colors.grey, 
                           constraints: const BoxConstraints(minHeight: 50), 
                           child: Center( 
                             child: Column( 
                                 mainAxisAlignment: MainAxisAlignment.center, 
                                 children: containers.map((item) => Draggable<Container>( 
                                     data: item, 
                                     child: item, 
                                     feedback: item, 
                                     childWhenDragging: Container(), 
                                     )).toList(), 
                                   ), 
                                 ), 
                              ); 
                         }, 
                            onWillAccept: (data) => true, 
                            onAccept: (data) { setState(() { 
                                               containers.add(data); 
                                              }); 
                                            },
                                   ),
                             ),

              const SizedBox(width: 20),  
              Column(                  mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                 children: draggableItems.map((item) => DragTarget<Container>( 
                              builder: (context, candidateData, rejectedData) { 
                                 return Draggable<Container>( 
                                          data: item, 
                                          feedback: item, 
                                          childWhenDragging: Container(), 
                                          child: item, 
                                           );                                 }, 
                               onWillAccept: (data) => true, 
                               onAccept: (data) { 
                                 setState(() { 
                                   draggableItems.remove(data); 
                                  }); 
                                }, 
                               )).toList(), 
             ),
            ], 
          ), 
     );
 }
}

Conclusion

In this post, we’ve explored the Draggable and DragTarget widgets in Flutter and their roles in implementing drag and drop functionality. By leveraging these widgets effectively, developers can create intuitive and interactive user experiences in their Flutter applications. Understanding the drag and drop process and utilizing the provided functionalities empowers developers to craft compelling user interfaces that enhance user engagement and usability.

Implementing drag and drop functionality using Flutter’s Draggable and DragTarget widgets opens up a world of possibilities for creating dynamic and interactive user interfaces. Whether you’re building a mobile app, a web application, or a desktop application, understanding these widgets’ functionalities and the drag and drop process is essential for crafting seamless user experiences.

FULL CODE IN OUR REPOSITORY HERE.

GET YOUR APP DEVELOPED BY IDIGISOL WEB TODAY! VISIT US HERE.