Search code examples
flutterflutter-layout

Flutter. Drag a Draggable item onto another Draggable item


I have the below board. There is an overlay (Stack) of 2 x 10 widgets, some transparent ones which are DragTargets and above them, the same width and height there are ones which are Draggable. The Draggable ones are the ones containing the images.

enter image description here

The problem that I'm facing is that the onWillAccept and onAccept methods from the ones below, are not called while I drag the ones above. I'm guessing because there are widgets overlaying them.

I've switched the widgets around, having the DragTargets overlay-ing the Draggable ones but now I can't drag them as they're below other widgets.

All examples of drag-and-drops are dragging an item from a place and placing it on another, one draggable, one dragTarget. I require a widget (or a zone on the screen) to be both draggable and a dragTarget. How could I accomplish this?

Here's the layout

          Align(
            child: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: AssetImage("images/user_board.jpg"),
                  alignment: Alignment.bottomCenter,
                ),
              ),
              height: _userBoardH,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Container(
                      height: _tileH,
                      child: Stack(children: <Widget>[
                        Row(
                          children: _buildSlots(ScreenBoard.FIRST_ROW),
                        ),
                        Row(
                          children: _buildTiles(ScreenBoard.FIRST_ROW),
                        ),
                      ])),
                  Container(
                      height: _tileH,
                      child: Stack(children: <Widget>[
                        Row(
                          children: _buildSlots(ScreenBoard.SECOND_ROW),
                        ),
                        Row(
                          children: _buildTiles(ScreenBoard.SECOND_ROW),
                        ),
                      ])),
                ],
              ),
            ),
            alignment: Alignment.bottomCenter,
          ),

Cheers.

EDIT

Solved it by following Patrick's suggestion. Here's the solution:

Widget _buildTile(Tile widget) {
  return DragTarget<Map>(
    builder: (context, candidateData, rejectedData) {
      return Container(
        child: Draggable<Map>(
          child: _getTile(widget),
          feedback: _getTile(widget),
          childWhenDragging: Container(
            width: widget._dimenW,
            height: widget._dimenH,
          ),
          data: {
            Tile.DATA_TILE_ROW_TYPE: widget._rowType,
            Tile.DATA_TILE_ROW_POS: widget._rowPosition,
            Tile.DATA_TILE_ID: widget._tileId,
          },
        ),
      );
    },
    onWillAccept: (data) {
      UDebug.log("onWillAccept");
      return false;
    },
    onAccept: (data) {
      UDebug.log("onAccept");
    },
  );
}

Solution

  • Wrap it in a Container() widget and put the image in a BoxDecoration() and use the child: property to hold your Draggable().

    This won't obstruct your pointer events.