Here is the problem that I am facing:
I start off with a list of emoji's which I want to drop into these 3 Drop Targets
(I want to be able to select each emoji which goes into each of these drop targets)
When I drag one of these emojis (only one, which is in this case, the first one, it automatically drops into all the drag targets instead of only the first one).
This results in the same emoji populating all the drag targets unintentionally like this which is unexpected behavior:
My question is, how can I change my code so that I can make sure that, when I drag on emoji into the first, second, or third Drag target, only that respective drag target gets filled instead of all of them? Thanks a lot and I really appreciate your help!
Code For DragBox:
class DragBox extends StatefulWidget {
DragBox({this.animatedAsset, this.width});
final LottieBuilder animatedAsset;
final double width;
@override
_DragBoxState createState() => _DragBoxState();
}
class _DragBoxState extends State<DragBox> {
@override
Widget build(BuildContext context) {
return Draggable(
feedback: Container(
width: 50,
height: 50,
child: widget.animatedAsset,
),
child: Container(
child: widget.animatedAsset,
width: widget.width,
height: 50,
),
childWhenDragging: Container(),
data: widget.animatedAsset,
);
}
}
Code For Emoji Picker :
class AnimatedEmojiPicker extends StatefulWidget {
@override
_AnimatedEmojiPickerState createState() => _AnimatedEmojiPickerState();
}
class _AnimatedEmojiPickerState extends State<AnimatedEmojiPicker> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 60,
decoration:
BoxDecoration(color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/blushing.json'),
),
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/cooldude.json'),
),
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/zipmouth.json'),
),
//More drag boxes like this one
],
),
),
);
}
}
My Drag targets:
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
),
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
],
),
Again, thanks for any help!
This is happening because on each DragTarget
you are building the same widget.caughtAnimation
that you set on any onAccept
callback.
Consider structuring your widget state model in a way that you can individually modify each DragTarget, this can be done with a List/array or a map.
List<LottieBuilder> caughtAnimations;
then
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[0] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[0],
),
);
},
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[1] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[1],
),
);
},
),
),
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[2] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[2],
),
);
},
),
],
),