2

I have been trying to add drag/drop support to my app, currently what I have come with is using this library:

reorderable_grid_view

I used this example code: code link

The reason I used this library is that it's smooth enough of animations when dragging. But what I want to do is to drag one item to another so that I can merge the one to another object when I drop. (It's like in Android/iOS home screen where you can drag apps to folders or drag into another that it creates a folder)

I have searched all the site but couldn't come across with such thing, only drag/drop libraries are available. Can anyone help me on this?

Thanks in advance.

Ali Yucel Akgul
  • 1,101
  • 8
  • 27
  • 53
  • https://api.flutter.dev/flutter/widgets/Draggable-class.html – rasityilmaz Oct 04 '22 at 15:35
  • @rasityilmaz not sure if this is what I am searching for. – Ali Yucel Akgul Oct 04 '22 at 16:06
  • EN(translate) - If you wrap the objects you use in the GridView with both draggable and drapTarget, any object can now accept both moved and moved objects. After this point, it remains only to organize events. TR - GridViewde kullandığınız nesneleri hem draggable ile hemde drapTarget ile sararsanız artık herhangi bir nesne hem taşınabilir hemde taşınan nesneyi kabul edebilir. Bu noktadan sonra sadece olayları düzenlemek kalır. – rasityilmaz Oct 04 '22 at 18:27
  • Flutter has a full tutorial about this: https://docs.flutter.dev/cookbook/effects/drag-a-widget – Lenny4 Apr 27 '23 at 01:47

1 Answers1

1

enter image description here

class MyHomePage extends StatelessWidget {
  MyHomePage({super.key});

  final ValueNotifier<List<ValueNotifier<List<Widget>>>> items = ValueNotifier([
    ValueNotifier([Text("A")]),
    ValueNotifier([Text("B")]),
    ValueNotifier([Text("C")]),
    ValueNotifier([Text("D")]),
  ]);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Expanded(
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 20.0),
              child: ValueListenableBuilder(
                valueListenable: items,
                builder: (BuildContext context, List<ValueNotifier<List<Widget>>> folders, Widget? child) {
                  return GridView.builder(
                      physics: const NeverScrollableScrollPhysics(),
                      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
                      itemCount: folders.length,
                      itemBuilder: (context, index) {
                        ValueNotifier<List<Widget>> item = folders[index];
                        return LongPressDraggable(
                          delay: const Duration(milliseconds: 500),
                          feedback: SizedBox(width: MediaQuery.of(context).size.width / 4, height: MediaQuery.of(context).size.width / 4, child: FittedBox(child: Icon(Icons.folder))),
                          data: index,
                          childWhenDragging: const SizedBox(),
                          child: DragTarget(
                            onAccept: (data) {
                              List<Widget> alreadyHaved = item.value;
                              alreadyHaved.addAll(folders[data as int].value);
                              item.value = alreadyHaved;
                              items.value.removeAt(data);
                              items.notifyListeners();
                            },
                            builder: (context, candidateData, rejectedData) {
                              return ValueListenableBuilder(
                                valueListenable: item,
                                builder: (BuildContext context, List<Widget> boxValues, Widget? child) {
                                  return Stack(children: [
                                    const Positioned.fill(
                                        child: FittedBox(
                                            child: Icon(
                                      Icons.folder,
                                      color: Colors.amber,
                                    ))),
                                    Positioned.fill(
                                      child: LayoutBuilder(
                                          builder: (p0, p1) => SizedBox(
                                              height: p1.maxHeight * .7,
                                              width: p1.maxWidth * .7,
                                              child: Center(
                                                child: Wrap(
                                                  children: boxValues,
                                                ),
                                              ))),
                                    )
                                  ]);
                                },
                              );
                            },
                          ),
                        );
                      });
                },
              ),
            ),
          ),
        ],
      ),
    );
  }
}
rasityilmaz
  • 764
  • 1
  • 6
  • 11