Notification texts go here Contact Us Buy Now!

Flutter: How to set boundaries for a Draggable widget?

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Test',
      home: GamePlay(),
    );
  }
}

class GamePlay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Row(
            children: [
              Container(
                width: 360,
                height: 400,
                decoration: BoxDecoration(
                  color: Colors.lightGreen,
                  border: Border.all(
                    color: Colors.green,
                    width: 2.0,
                  ),
                ),
              ),
              Container(
                width: 190,
                height: 400,
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(
                    color: Colors.purple,
                    width: 2.0,
                  ),
                ),
              ),
            ],
          ),
          DragObject(
              key: GlobalKey(),
              initPos: Offset(365, 0.0),
              id: 'Item 1',
              itmColor: Colors.orange),
          DragObject(
            key: GlobalKey(),
            initPos: Offset(450, 0.0),
            id: 'Item 2',
            itmColor: Colors.pink,
          ),
        ],
      ),
    );
  }
}

class DragObject extends StatefulWidget {
  final String id;
  final Offset initPos;
  final Color itmColor;

  DragObject({Key key, this.id, this.initPos, this.itmColor}) : super(key: key);

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

class _DragObjectState extends State<DragObject> {
  GlobalKey _key;
  Offset position;
  Offset posOffset = Offset(0.0, 0.0);

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
    _key = widget.key;
    position = widget.initPos;
    super.initState();
  }

  void _getRenderOffsets() {
    final RenderBox renderBoxWidget = _key.currentContext.findRenderObject();
    final offset = renderBoxWidget.localToGlobal(Offset.zero);

    posOffset = offset - position;
  }

  void _afterLayout(_) {
    _getRenderOffsets();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      left: position.dx,
      top: position.dy,
      child: Listener(
        child: Draggable(
          child: Container(
            width: 80,
            height: 80,
            color: widget.itmColor,
          ),
          feedback: Container(
            width: 82,
            height: 82,
            color: widget.itmColor,
          ),
          childWhenDragging: Container(),
          onDragEnd: (drag) {
            setState(() {
              if (drag.offset.dx > 0) {
                position = drag.offset - posOffset;
              } else {
                position = widget.initPos;
              }
            });
          },
        ),
      ),
    );
  }
}

In this code, we are using a Draggable widget to enable the dragging of objects within a container. The Draggable widget is configured with a child, which is the object to be dragged, and a feedback widget, which is displayed while the object is being dragged. The onDragEnd callback is used to update the position of the object when the drag operation is completed.

To ensure that the object cannot be dragged outside of the container, we have added a check in the onDragEnd callback. This check compares the new position of the object with the width of the container and updates the position only if it is within the container. Otherwise, the position is reset to its initial value.

Here's the explanation of the relevant parts of the code:

  • Draggable Widget: We use the Draggable widget to enable dragging of objects. It takes the child widget to be dragged, a feedback widget to be displayed during dragging, and a callback for handling drag events.
  • Feedback Widget: The feedback widget is displayed while the object is being dragged. In this case, it's a container with the same size and color as the child widget.
  • onDragEnd Callback: This callback is invoked when the drag operation is completed. It takes the DragEndDetails object as an argument, which contains information about the drag operation, such as the new position of the object.
  • Position Update: Inside the onDragEnd callback, we check if the new position of the object is greater than 0. This ensures that the object is dragged within the container. If it is, we update the position of the object. Otherwise, we reset the position to its initial value.

With these modifications, the object can now be dragged within the container and will be constrained within the container's boundaries.

Post a Comment

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.