Given a list of items in a drawer, is it somehow possible to drag one of these items from the drawer onto the body of the scaffold and into the DragTarget?
Below is a simplified example that shows what I would generally like to happen. Except when I Pop the Navigator, the Draggable context also dissapears as this is obviously part of the Drawer. I'm not sure how to solve this problem. Or if this is even possible...
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String droppedItem = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Drag and Drop Example'),
),
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.grey,
child: DragTarget<String>(
onWillAcceptWithDetails: (details) {
setState(() {
droppedItem = details.data;
});
return true;
},
builder: (context, candidateData, rejectedData) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(
Icons.cloud_upload,
size: 50,
color: Colors.blue,
),
Text(
'Drop Here : \n $droppedItem',
style: const TextStyle(fontSize: 20),
),
],
);
},
),
),
),
drawer: Drawer(
child: ListView(
children: <Widget>[
Draggable<String>(
data: 'Item 1',
feedback: Container(
color: Colors.deepOrange,
height: 50,
width: 50,
child: const Icon(Icons.directions_run),
),
childWhenDragging: const ListTile(
title: Text('Item 1'),
leading: Icon(Icons.drag_handle), // Placeholder icon
),
child: const ListTile(
title: Text('Item 1'),
leading: Icon(Icons.drag_handle), // Placeholder icon
),
// onDragStarted: () {
// Navigator.pop(context);
// },
),
Draggable<String>(
data: 'Item 2',
feedback: Container(
color: Colors.deepOrange,
height: 50,
width: 50,
child: const Icon(Icons.directions_run),
),
childWhenDragging: const ListTile(
title: Text('Item 2'),
leading: Icon(Icons.drag_handle), // Placeholder icon
),
child: const ListTile(
title: Text('Item 2'),
leading: Icon(Icons.drag_handle), // Placeholder icon
),
// onDragStarted: () {
// Navigator.pop(context);
// },
),
],
),
),
);
}
}
This may not suit your usecase if it's a requirement to use a drawer, BUT: you could map the button on the scaffold to bring on a custom widget that masquerades as a drawer as an Overlay. That gives you a ton of power in that situation:
Here's my refactor. Note that if you want shadows, complex gestures, or a number of other drawer-like scenarios you would need to further adjust that starting code.
The main focus of this example is just to demonstrate that you could achieve something similar to (though in fairness: not exactly) what you asked for by using Overlays and animation controllers.
EDIT
I accidentally uploaded your baseline code, not my changed code. Whoops. That wouldn't have been helpful... Fixed now.