More
Building a Drag-and-Drop Flutter App with Draggable Widgets and Back4App
22 min
introduction interactive drag and drop interfaces enhance user experience by allowing users to manipulate ui elements intuitively flutter provides the draggable and dragtarget widgets to create such interactions in this tutorial, you will learn how to build a flutter application that uses draggable widgets to move items between lists, with data persistence using back4app—a backend as a service powered by parse server by the end of this tutorial, you will have a functional flutter app where users can drag items from one list to another, and the changes will be stored and retrieved from back4app this tutorial is suitable for flutter developers of all experience levels prerequisites to complete this tutorial, you will need flutter sdk installed on your machine follow the official flutter installation guide https //flutter dev/docs/get started/install for your operating system basic knowledge of flutter and dart if you're new to flutter, review the flutter documentation https //flutter dev/docs to familiarize yourself with the basics an ide or text editor such as visual studio code or android studio a back4app account sign up for a free account at back4app https //www back4app com/ parse server sdk for flutter added to your project learn how to set it up by following the back4app flutter sdk guide https //www back4app com/docs/flutter/parse flutter sdk overview we will build a task management app where tasks can be dragged from a "to do" list to a "completed" list and vice versa the app will use draggable widgets to enable dragging of tasks use dragtarget widgets to define drop zones store and retrieve tasks from back4app to persist data step 1 – setting up the flutter project 1 1 create a new flutter project open your terminal and run flutter create drag drop app navigate to the project directory cd drag drop app 1 2 add dependencies open pubspec yaml and add the following dependencies dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 run flutter pub get to install the packages step 2 – setting up back4app 2 1 create a new back4app application log in to your back4app dashboard https //dashboard back4app com/ click on "create new app" enter a name for your application, e g , "dragdropapp" , and click "create" 2 2 set up the data model in your application dashboard, navigate to the "database" section click on "create a class" in the modal select "custom" enter "task" as the class name click "create class" 2 3 add columns to the class in the "task" class, click on "+" to add new columns add the following columns title type string status type string add some sample data to the "task" class for example 2 4 obtain application credentials navigate to app settings > security & keys note down your application id and client key step 3 – initializing parse in your flutter app open lib/main dart and modify it as follows import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'screens/home page dart'; // you'll create this file next void main() async { widgetsflutterbinding ensureinitialized(); const keyapplicationid = 'your application id'; const keyclientkey = 'your client key'; const keyparseserverurl = 'https //parseapi back4app com'; await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, debug true, ); runapp(myapp()); } class myapp extends statelesswidget { @override widget build(buildcontext context) { return materialapp( title 'drag and drop app', theme themedata( primaryswatch colors blue, ), home homepage(), ); } } replace 'your application id' and 'your client key' with your actual back4app credentials step 4 – creating the task model create a new directory called models under lib and add a file named task dart // lib/models/task dart class task { string id; string title; string status; task({required this id, required this title, required this status}); } step 5 – fetching tasks from back4app create a new directory called services under lib and add a file named task service dart // lib/services/task service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/task dart'; class taskservice { future\<list\<task>> gettasksbystatus(string status) async { final querybuilder\<parseobject> query = querybuilder\<parseobject>(parseobject('task')) whereequalto('status', status); final parseresponse apiresponse = await query query(); if (apiresponse success && apiresponse results != null) { return apiresponse results! map((data) { return task( id data objectid!, title data get\<string>('title') ?? '', status data get\<string>('status') ?? '', ); }) tolist(); } else { return \[]; } } future\<void> updatetaskstatus(string id, string status) async { var task = parseobject('task') objectid = id set('status', status); await task save(); } } step 6 – building the ui with draggable and dragtarget create a new directory called screens under lib and add a file named home page dart // lib/screens/home page dart import 'package\ flutter/material dart'; import ' /models/task dart'; import ' /services/task service dart'; class homepage extends statefulwidget { @override homepagestate createstate() => homepagestate(); } class homepagestate extends state\<homepage> { final taskservice taskservice = taskservice(); list\<task> todotasks = \[]; list\<task> completedtasks = \[]; @override void initstate() { super initstate(); fetchtasks(); } future\<void> fetchtasks() async { var todo = await taskservice gettasksbystatus('to do'); var completed = await taskservice gettasksbystatus('completed'); setstate(() { todotasks = todo; completedtasks = completed; }); } void ondragaccept(task task, string newstatus) async { await taskservice updatetaskstatus(task id, newstatus); await fetchtasks(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('drag and drop tasks'), ), body row( children \[ expanded( child taskcolumn( title 'to do', tasks todotasks, ondragaccept (task) => ondragaccept(task, 'to do'), ), ), expanded( child taskcolumn( title 'completed', tasks completedtasks, ondragaccept (task) => ondragaccept(task, 'completed'), ), ), ], ), ); } } class taskcolumn extends statelesswidget { final string title; final list\<task> tasks; final function(task) ondragaccept; taskcolumn({ required this title, required this tasks, required this ondragaccept, }); @override widget build(buildcontext context) { return dragtarget\<task>( onwillaccept (task) => true, onaccept (task) { ondragaccept(task); }, builder (context, candidatedata, rejecteddata) { return container( padding edgeinsets all(16 0), child column( children \[ text( title, style textstyle(fontsize 22, fontweight fontweight bold), ), expanded( child listview( children tasks map((task) { return draggable\<task>( data task, feedback material( child taskcard(task task), elevation 4 0, ), childwhendragging opacity( opacity 0 5, child taskcard(task task), ), child taskcard(task task), ); }) tolist(), ), ), ], ), ); }, ); } } class taskcard extends statelesswidget { final task task; taskcard({required this task}); @override widget build(buildcontext context) { return card( margin edgeinsets symmetric(vertical 8 0), child listtile( title text(task title), ), ); } } explanation homepage the main screen that displays two columns—"to do" and "completed" tasks taskcolumn a widget that displays tasks and acts as a dragtarget for draggable tasks taskcard a widget to display individual task information step 7 – running the app 7 1 run the app in your terminal, run flutter run 7 2 test drag and drop functionality drag a task from the "to do" column and drop it into the "completed" column the task's status should update, and it should appear under "completed" the change persists in back4app; if you restart the app, the task remains in its new status conclusion in this tutorial, you learned how to implement drag and drop functionality in a flutter application using draggable and dragtarget widgets you integrated back4app to store and retrieve task data, allowing for data persistence across sessions this interactive app demonstrates how to enhance user experience with intuitive ui elements and a scalable backend key takeaways draggable widgets enable users to drag ui elements dragtarget widgets define drop zones for draggable items back4app integration provides a backend to store and manage data next steps add authentication implement user authentication to have personalized task lists enhance ui/ux add animations, custom icons, and improved layouts real time updates use back4app's live queries to update tasks in real time across multiple devices error handling implement error handling for network issues and data conflicts additional resources back4app documentation https //www back4app com/docs parse sdk for flutter guide https //docs parseplatform org/flutter/guide/ flutter official documentation https //flutter dev/docs draggable widget https //api flutter dev/flutter/widgets/draggable class html dragtarget widget https //api flutter dev/flutter/widgets/dragtarget class html happy coding!