Search code examples
flutterdartdraggabledragtarget

DragTarget doesnt call onWillAccept with custom Draggable (Flutter)


I am trying to make Tags which are draggable text so that I can drag them to one of 2 DragTarget I have (ideally being able to move them between 3 DragTarget). Unfortunately I can't make them interact with the DragTargets as they dont even call onWillAccept(). My draggables are DragabbleTag and extends Draggable and my dragTargets are in a Stateful Widget and should accept them.

import 'package:myApp/components/draggableTag.dart';
import 'package:flutter/material.dart';

class DraggableTagTarget extends StatefulWidget {
  final String title;
  final int maxTagAmount;
  final Color backgroundColor;
  final List<DraggableTag> tagsPool;

  const DraggableTagTarget(
      {Key key,
      this.title,
      this.backgroundColor,
      this.tagsPool,
      this.maxTagAmount})
      : super(key: key);

  @override
  _DraggableTagTargetState createState() => _DraggableTagTargetState();
}

class _DraggableTagTargetState extends State<DraggableTagTarget> {
  String test = "Test";

  @override
  Widget build(BuildContext context) {
    return DragTarget<DraggableTag>(onAccept: (DraggableTag value) {
      setState(() {
        widget.tagsPool.add(value);
        test = value.label;
      });
    }, onWillAccept: (DraggableTag data) {
      bool result =
          widget.tagsPool.length <= widget.maxTagAmount ? true : false;
      debugPrint("ONWillAccept: " + data.label + " = " + result.toString());
      return result;
    }, builder: (context, candidateData, rejectedData) {
      return Container(
        decoration: new BoxDecoration(
          color: widget.backgroundColor,
          border: Border.all(
            color: Colors.black,
          ),
        ),
        child: Column(
          children: <Widget>[
            Text(test),
            Text(widget.title),
            SizedBox(
              height: 60,
              child: Wrap(
                children: widget.tagsPool,
              ),
            ),
          ],
        ),
      );
    });
  }
}

Custom DragTarget 'DraggableTagTarget'

import 'package:flutter/material.dart';

class DraggableTag extends Draggable<String> {
  final String label;

  DraggableTag({Key key, this.label})
      : super(
          key: key,
          data: label,
          child: idleTag(label),
          feedback: feedbackTag(label),
          childWhenDragging: ghostTag(label),
        );

  static Widget idleTag(String label) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2.0),
      child: Text(
        label,
        style: TextStyle(
          fontSize: 16,
        ),
      ),
      decoration: BoxDecoration(
        color: Colors.blue,
        border: Border.all(
          color: Colors.black,
        ),
        borderRadius: BorderRadius.all(Radius.circular(20)),
      ),
    );
  }

Custom Draggable 'DraggableTag' I excluded feedbackTag() and ghostTag which shouldnt be relevant

At first my draggableTag was extending a widget but seeing some similar problem I made it into extending directly a Draggable but it didnt help

EDIT: I am assigning ma values to draggable in a custom DialogWidget (stateful widget) in a list


class _RatingDialogState extends State<RatingDialog> {
  List<DraggableTag> tagsPool = [
    DraggableTag(label: "Acting"),
    DraggableTag(label: "Scenario"),
    DraggableTag(label: "Pace"),
    DraggableTag(label: "Length"),
    DraggableTag(label: "Message"),
  ];
  List<DraggableTag> negativeTagsPool = [];
  List<DraggableTag> positiveTagsPool = [];

  @override
  Widget build(BuildContext context) {
    return Dialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      elevation: 0,
      backgroundColor: Colors.transparent,
      child: contentBox(context),
    );
  }

  contentBox(context) {
    return Stack(
  ...
             Wrap(
                children: tagsPool,
              ),
              SizedBox(height: 22),
              Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    Flexible(
                      child: FractionallySizedBox(
                        widthFactor: 0.85,
                        child: DraggableTagTarget(
                            title: "Negative",
                            backgroundColor: Colors.red,
                            tagsPool: negativeTagsPool,
                            maxTagAmount: 3),
                      ),
                    ),
                    Flexible(
                      child: FractionallySizedBox(
                        widthFactor: 0.85,
                        child: DraggableTagTarget(
                            title: "Positive",
                            backgroundColor: Colors.green,
                            tagsPool: positiveTagsPool,
                            maxTagAmount: 3),
                      ),
                    ),
                  ]),
...

SOLUTION: as ikerfah explained, I didnt put the right type into <> because I was confused to what my DraggableTag class was. I made another class to contains the data Tag so that both my DragTarget and DraggableTag use this class


Solution

  • Draggable and DragTarget must have the same generic type, but you have Draggable<String> and DragTarget<DraggableTag>