4

When exploring the Flutter's DragTarget class I could not find any mechanism to hook to the 'on hover event' if you will. Here is an example:

 class DropZone extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 40,
      color: Colors.green,
      child: DragTarget(
          builder: (context, List<int> candidateData, rejectedData) {
            print("dragged");
            return new Container(color: Colors.red,);
          },
      onWillAccept: (data) {
            return true;
      },),
    );
  }
}

I would like to change the color of the container when a Draggable object is hovered but not yet dropped. The builder method, in this case, only executes during the initial rendering and when the Draggable leaves the target. I suspect I have to do something in the onWillAccept method but not sure what. Does anybody have a solution?

1
  • are you using the positioned widget? Commented Dec 30, 2018 at 21:28

3 Answers 3

3

here is the code for what I think you're looking for

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: App(),
      ),
    );
  }
}

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  Color caughtColor = Colors.grey;
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        DragBox(Offset(0.0, 0.0), Colors.green),
        Positioned(
            left: 100,
            bottom: 0.0,
            child: DragTarget(onAccept: (Color color) {
              caughtColor = color;
            }, builder: (
              BuildContext context,
              List<dynamic> accepted,
              List<dynamic> rejected,
            ) {
              return Container(
                width: 200,
                height: 200,
                color: accepted.isEmpty ? caughtColor : Colors.grey.shade200,
              );
            }))
      ],
    );
  }
}

class DragBox extends StatefulWidget {
  final Offset initPos;
  final Color itemColor;

  DragBox(this.initPos, this.itemColor);
  @override
  _DragBoxState createState() => _DragBoxState();
}

class _DragBoxState extends State<DragBox> {
  Offset position = Offset(0.0, 0.0);

  @override
  void initState() {
    super.initState();
    position = widget.initPos;
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Draggable(
        data: widget.itemColor,
        child: Container(
          width: 100,
          height: 100,
          color: widget.itemColor,
        ),
        onDraggableCanceled: (velocity, offset) {
          setState(() {
            position = offset;
          });
        },
        feedback: Container(
          width: 120,
          height: 120,
          color: widget.itemColor.withOpacity(0.5),
        ),
      ),
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

3

You can use the candidateData parameter in the DragTarget.builder:

...
border: Border.all(
           color: candidateData.isNotEmpty
            ? Colors.red
            : Colors.black)),

The code above changes the border color to red upon hover.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

You can make combination of onAccept, onMove and onLeave functions in DragTarget to achieve the result.

Here is how you do it:

// ...
bool isTargetGettingDroppedForDelete = false;
//...

DragTarget<String>(
        builder: (
          BuildContext context,
          List<dynamic> accepted,
          List<dynamic> rejected,
        ) {
          return Container(
            height: 100,
            width: 100,
            color: isTargetGettingDroppedForDelete ? Colors.red : Colors.green,
          );
        },
        onWillAccept: (data) {
          return data == Constants.draggable;
        },
        onAccept: (data) {
          setState(() {
            isTargetGettingDroppedForDelete = false;
          });
        },
        onMove: (details) {
          setState(() {
            isTargetGettingDroppedForDelete = true;
          });
        },
        onLeave: (data) {
          setState(() {
            isTargetGettingDroppedForDelete = false;
          });
        },
      ),

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.