Home > Net >  how to perform drag operation on widget with Gesturedetector flutter
how to perform drag operation on widget with Gesturedetector flutter

Time:07-06

I want to drag and drop my custom widget with gesture detector. It is showing x- direction and y- direction values but not dragging to anywhere on screen.

Here is my code:

layoutpage:

SizedBox(
                  width: MediaQuery.of(context).size.width,
                  height: MediaQuery.of(context).size.height,
                  child: Stack(
                      children: _layoutProvider.tables
                          .map(
                            (SectionTable sTable) => Positioned(
                              top: sTable.top,
                              left: sTable.left,
                              child: LayoutWidget(
                                width: sTable.width,
                                height: sTable.height,
                                type: sTable.type.index,
                                name: sTable.name,
                                left: sTable.left,
                                top: sTable.top,
                                rotate: sTable.rotate,
                                color: sTable.order != null
                                    ? Colors.green
                                    : Colors.grey,
                                seats: sTable.seats,
                               
                                
                              ),
                            ),
                          )
                          .toList()),
                ),

LayoutWidget:

class LayoutWidget extends StatefulWidget {
  late  double width;
  late  double height;
  late double left;
  late  double top;


  LayoutWidget({
    Key? key,
    required this.width,
    required this.height,
    required this.left,
    required this.top,
   
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _LayoutWidgetState();
}

class _LayoutWidgetState extends State<LayoutWidget> {


  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        RotationTransition(
          turns: widget.type == 0
              ? const AlwaysStoppedAnimation(0)
              : AlwaysStoppedAnimation(rotationValue / 360),
          child: GestureDetector(
            onPanUpdate: (details) {
              widget.top =  widget.top  details.delta.dy;
              widget.left =  widget.left  details.delta.dx;

              setState(() {

              });
            },
            onTap: () {
              setState(() {
                showMenu = !showMenu;
              });
            },
            child: myWidget()
}

Can anyone help why i am unable to drag on screen. Thanks.

CodePudding user response:

I hope you you can get Idea from this code. In this code you can drag Container anywhere in the Screen and set it. And also check this Gesture Detector Overview for Gesture Detector detail.

import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class GestureDetectorPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      color: Colors.grey[100],
      width: double.infinity,
      height: double.infinity,
      child: MainContent(),
      ),
    );
  }
}

class MainContent extends StatefulWidget {
 @override
_MainContentState createState() => _MainContentState();
}

class _MainContentState extends State<MainContent> {
  GlobalKey key = GlobalKey();

  String dragDirection = '';
  String startDXPoint = '50';
  String startDYPoint = '50';
  String dXPoint;
  String dYPoint;
  String velocity;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
       onHorizontalDragStart: _onHorizontalDragStartHandler,
       onVerticalDragStart: _onVerticalDragStartHandler,
       onHorizontalDragUpdate: _onDragUpdateHandler,
       onVerticalDragUpdate: _onDragUpdateHandler,
       onHorizontalDragEnd: _onDragEnd,
       onVerticalDragEnd: _onDragEnd,
       dragStartBehavior: DragStartBehavior.start, // default
       behavior: HitTestBehavior.translucent,
       child: Stack(
         children: [
           Positioned(
             left: double.parse(this.startDXPoint),
             top: double.parse(this.startDYPoint),
             child: Container(
               decoration: BoxDecoration(
               color: Colors.green,
               borderRadius: BorderRadius.circular(100)
             ),
             child: Center(
               child: Padding(
                 padding: const EdgeInsets.all(20),
                   child: Text('Draggable', style: TextStyle(fontSize: 14, color: Colors.white),),
               ),
             ),
           )
         ),
       ],
     ),
   );
 }

void _onHorizontalDragStartHandler(DragStartDetails details) {
  setState(() {
    this.dragDirection = "HORIZONTAL";
    this.startDXPoint = '${details.globalPosition.dx.floorToDouble()}';
    this.startDYPoint = '${details.globalPosition.dy.floorToDouble()}';
  });
}

/// Track starting point of a vertical gesture
void _onVerticalDragStartHandler(DragStartDetails details) {
  setState(() {
    this.dragDirection = "VERTICAL";
    this.startDXPoint = '${details.globalPosition.dx.floorToDouble()}';
    this.startDYPoint = '${details.globalPosition.dy.floorToDouble()}';
 });
}

void _onDragUpdateHandler(DragUpdateDetails details) {
  setState(() {
    this.dragDirection = "UPDATING";
    this.startDXPoint = '${details.globalPosition.dx.floorToDouble()}';
    this.startDYPoint = '${details.globalPosition.dy.floorToDouble()}';
  });
}

/// Track current point of a gesture
void _onHorizontalDragUpdateHandler(DragUpdateDetails details) {
  setState(() {
    this.dragDirection = "HORIZONTAL UPDATING";
    this.dXPoint = '${details.globalPosition.dx.floorToDouble()}';
    this.dYPoint = '${details.globalPosition.dy.floorToDouble()}';
    this.velocity = '';
  });
}

/// Track current point of a gesture
void _onVerticalDragUpdateHandler(DragUpdateDetails details) {
  setState(() {
    this.dragDirection = "VERTICAL UPDATING";
    this.dXPoint = '${details.globalPosition.dx.floorToDouble()}';
    this.dYPoint = '${details.globalPosition.dy.floorToDouble()}';
    this.velocity = '';
  });
}

/// What should be done at the end of the gesture ?
void _onDragEnd(DragEndDetails details) {
  double result = details.velocity.pixelsPerSecond.dx.abs().floorToDouble();
  setState(() {
    this.velocity = '$result';
  });
 }

}

CodePudding user response:

You can use the Draggable widget instead. Please try this

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const MyStatefulWidget(),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int acceptedData = 0;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        Draggable<int>(
          // Data is the value this Draggable stores.
          data: 10,
          feedback: Container(
            color: Colors.deepOrange,
            height: 100,
            width: 100,
            child: const Icon(Icons.directions_run),
          ),
          childWhenDragging: Container(
            height: 100.0,
            width: 100.0,
            color: Colors.pinkAccent,
            child: const Center(
              child: Text('Child When Dragging'),
            ),
          ),
          child: Container(
            height: 100.0,
            width: 100.0,
            color: Colors.lightGreenAccent,
            child: const Center(
              child: Text('Draggable'),
            ),
          ),
        ),
        DragTarget<int>(
          builder: (
            BuildContext context,
            List<dynamic> accepted,
            List<dynamic> rejected,
          ) {
            return Container(
              height: 100.0,
              width: 100.0,
              color: Colors.cyan,
              child: Center(
                child: Text('Value is updated to: $acceptedData'),
              ),
            );
          },
          onAccept: (int data) {
            setState(() {
              acceptedData  = data;
            });
          },
        ),
      ],
    );
  }
}
  • Related