SinaMN75
SinaMN75

Reputation: 7621

Drag items without drag target in flutter

I have a list of Widgets.

  List<Widget> list = <Widget>[];

that I update the list on click of a button and add widgets inside it.

  void addWidgets() => setState(() => list.add(Draggable(
        child: Text("data"),
        feedback: Material(child: Text("data")),
        childWhenDragging: Container(),
      )));

I want to able to drag the items on the screen wherever user drags them, not on a specific place. Kind of like instagram story creator.

in this code the widgets are draggable, but jumps back to it original place when user stop dragging.

Upvotes: 1

Views: 1186

Answers (1)

litt
litt

Reputation: 168

You can make draggable widgets without using the Default Draggable Class. I've made one with the matrix_gesture_detector package.

The code below not only lets you to drag the widgets. You can also resize them by pinch zooming with your two fingers just like the Instagram stories.

You can customize the list according to your use case. Here is the full code.

import "package:flutter/material.dart";
import 'package:flutter/rendering.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';

class TextOverImage extends StatefulWidget {
  @override
  _TextOverImageState createState() => _TextOverImageState();
}

class _TextOverImageState extends State<TextOverImage> {
  List<Widget> list = [
    DraggableWidget(
        draggableWidget:
            Container(color: Colors.green, height: 100, width: 100)),
    DraggableWidget(
        draggableWidget: Container(color: Colors.red, height: 70, width: 70)),
    DraggableWidget(
        draggableWidget: Container(color: Colors.black, height: 20, width: 20)),
  ];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Column(
          children: [
            Center(
              child: Container(
                height: 400,
                width: 400,
                color: Colors.blue,
                child: Stack(
                  children: list,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class DraggableWidget extends StatefulWidget {
  final Widget draggableWidget;
  DraggableWidget({Key key, this.draggableWidget}) : super(key: key); // changed

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

class _DraggableWidgetState extends State<DraggableWidget> {
  double scale = 0.0;

  @override
  Widget build(BuildContext context) {
    final ValueNotifier<Matrix4> notifier = ValueNotifier(Matrix4.identity());

    return Center(
      child: MatrixGestureDetector(
        onMatrixUpdate: (m, tm, sm, rm) {
          notifier.value = m;
        },
        child: AnimatedBuilder(
          animation: notifier,
          builder: (ctx, child) {
            return Transform(
              transform: notifier.value,
              child: Center(
                child: Stack(
                  children: <Widget>[
                    Transform.scale(
                      scale:
                          1, 
                      origin: Offset(0.0, 0.0),
                      child: widget.draggableWidget,
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

Hope this helps you, pal. Peace.

Upvotes: 1

Related Questions