Kinda Code
Home/Flutter/Flutter Draggable example

Flutter Draggable example

Last updated: March 24, 2023

This concise article shows you how to use the Draggable widget in Flutter through a full example.

In general, the Draggable widget goes along with the DragTarget widget:

  • Draggable: Creates a widget that can be dragged to a target.
  • DragTarget: Receives data when a dragged widget is dropped.

Below is a complete example of implementing the Draggable widget in Flutter.

Example

Preview

Our example app contains 2 boxes. The first one displays a network image and is draggable. The second one is just a color box at the beginning, but it can take the dragged image and then displays it.

The complete code

The full source code with explanations:

// main.dart
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 const MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // the image that will be displayed in the target
  String? _targetImageUrl;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(25),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              /// Draggable
              Draggable<String>(
                data:
                    "https://www.kindacode.com/wp-content/uploads/2020/11/my-dog.jpg",
                // The widget to show under the pointer when a drag is under way
                feedback: Opacity(
                  opacity: 0.4,
                  child: Container(
                    color: Colors.purple,
                    width: 300,
                    height: 200,
                    alignment: Alignment.center,
                    child: Image.network(
                      'https://www.kindacode.com/wp-content/uploads/2020/11/my-dog.jpg',
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
                child: Container(
                  width: 300,
                  height: 200,
                  alignment: Alignment.center,
                  color: Colors.purple,
                  child: Image.network(
                    'https://www.kindacode.com/wp-content/uploads/2020/11/my-dog.jpg',
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              const SizedBox(height: 50),

              /// Target
              DragTarget<String>(
                onAccept: (value) {
                  setState(() {
                    _targetImageUrl = value;
                  });
                },
                builder: (_, candidateData, rejectedData) {
                  return Container(
                    width: 300,
                    height: 200,
                    color: Colors.amber,
                    alignment: Alignment.center,
                    child: _targetImageUrl != null
                        ? Image.network(
                            _targetImageUrl!,
                            fit: BoxFit.cover,
                          )
                        : Container(),
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}

This example is quite simple, but from here, you’re good to go.

API

Draggable constructor:

Draggable({
  Key? key, 
  required Widget child, 
  required Widget feedback, 
  T? data, 
  Axis? axis, 
  Widget? childWhenDragging, 
  Offset feedbackOffset = Offset.zero, 
  DragAnchorStrategy? dragAnchorStrategy, 
  Axis? affinity, 
  int? maxSimultaneousDrags, 
  VoidCallback? onDragStarted, 
  DragUpdateCallback? onDragUpdate, 
  DraggableCanceledCallback? onDraggableCanceled, 
  DragEndCallback? onDragEnd, 
  VoidCallback? onDragCompleted, 
  bool ignoringFeedbackSemantics = true, 
  bool rootOverlay = false, 
  HitTestBehavior hitTestBehavior = HitTestBehavior.deferToChild
})

DragTarget constructor:

DragTarget({
  Key? key, 
  required DragTargetBuilder<T> builder, 
  DragTargetWillAccept<T>? onWillAccept, 
  DragTargetAccept<T>? onAccept, 
  DragTargetAcceptWithDetails<T>? onAcceptWithDetails, 
  DragTargetLeave<T>? onLeave, 
  DragTargetMove<T>? onMove, 
  HitTestBehavior hitTestBehavior = HitTestBehavior.translucent
})

Afterword

We’ve built a little beautiful and vivid app that makes use of the Draggable widget to let the user drag and drop things. If you’d like to explore more new and exciting stuff about modern Flutter development, take a look at the following articles:

You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.