Andrey
Andrey

Reputation: 191

Flutter DragTarget on hover

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?

Upvotes: 4

Views: 2867

Answers (3)

Daniel Z.
Daniel Z.

Reputation: 95

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.

Upvotes: 3

Akash
Akash

Reputation: 3

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;
          });
        },
      ),

Upvotes: 0

flutter
flutter

Reputation: 6766

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),
        ),
      ),
    );
  }
}

Upvotes: 3

Related Questions