I'm starting with Flutter and I cannot make drag and drop functionality to work. I followed the documentation but have no idea what I'm doing wrong. This sample app displays three squares and the blue is draggable. The other ones have DragTarget set, one inside the square and one outside the square. When I drag the blue square it prints info that the drag started but there is no print info when dragging or dropping over the DragTargets. Here is the code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
constraints: BoxConstraints.expand(),
color: Colors.grey[900],
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
child: DragTarget(
onWillAccept: (d) => true,
onAccept: (d) => print("ACCEPT 1!"),
onLeave: (d) => print("LEAVE 1!"),
builder: (a,data,c) {
print(data);
return Center();
},
),
),
DragTarget(
onWillAccept: (d){return true;},
onAccept:(d) => print("ACCEPT 2!"),
onLeave: (d) => print("LEAVE 2!"),
builder: (context, candidateData, rejectedData){
return Container(
width: 150,
height: 150,
color: Colors.purple
);
}
),
Draggable(
data: ["SOME DATA"],
onDragStarted: () => print("DRAG START!"),
onDragCompleted: () => print("DRAG COMPLETED!"),
onDragEnd: (details) => print("DRAG ENDED!"),
onDraggableCanceled: (data, data2) => print("DRAG CANCELLED!"),
feedback: SizedBox(
width: 100,
height: 100,
child: Container(
margin: EdgeInsets.all(10),
color: Colors.green[800],
),
),
child: SizedBox(
width: 100,
height: 100,
child: Container(
margin: EdgeInsets.all(10),
color: Colors.blue[800],
),
),
),
],
)
),
)
);
}
}
Apparently the Draggable and DragTarget need to have the generic type specified if you are passing data, otherwise the onAccept and onWillAccept will not be fired.
For example, if you want to pass data as int then use Draggable<int>
and DragTarget<int>
— this also applies to onAccept and onWillAccept, they need to accept int as a parameter.
You should setState when you call onAccept and add a boolean value to your stateful widget.
bool accepted = false;
onAccept: (data){
if(data=='d'){
setState(() {
accepted = true;
});
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With