Setting Boundaries to ReorderableListView

420 views Asked by At

How to set a boundary to the dragging of the Child Widget inside ReorderableListView

Current Output : -

Expected Output : -

Draggable Child Widget should not move further than the blue Container Widget.

Code to reproduce the issue : -

import 'package:flutter/material.dart';

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

class ReorderableApp extends StatelessWidget {
  const ReorderableApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ReorderableListView Sample')),
        body: const ReorderableExample(),
      ),
    );
  }
}

class ReorderableExample extends StatefulWidget {
  const ReorderableExample({super.key});

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

class _MyStatefulWidgetState extends State<ReorderableExample> {
  final List<int> _items = List<int>.generate(20, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 300,
        width: 300,
        color: Colors.blue[100],
        padding: const EdgeInsets.all(10),
        child: Center(
          child: ReorderableListView(
            padding: const EdgeInsets.symmetric(vertical: 10),
            children: <Widget>[
              for (int index = 0; index < _items.length; index += 1)
                Container(
                  key: Key('$index'),
                  height: 60,
                  margin: const EdgeInsets.all(5),
                  color: Colors.blue[400],
                  alignment: Alignment.center,
                  child: Text('Item ${_items[index]}'),
                ),
            ],
            onReorder: (int oldIndex, int newIndex) {
              setState(() {
                if (oldIndex < newIndex) {
                  newIndex -= 1;
                }
                final int item = _items.removeAt(oldIndex);
                _items.insert(newIndex, item);
              });
            },
          ),
        ),
      ),
    );
  }
}
1

There are 1 answers

1
Alex Sunder Singh On

Finally, after lot of research, I found a solution for this requirement with Overlay and OverlayEntry

Here is a code

class _MyStatefulWidgetState extends State<ReorderableExample> {
  final List<int> _items = List<int>.generate(20, (int index) => index);

  @override
  Widget build(BuildContext context) {

    return Center(
      child: Container(
        height: 300,
        width: 300,
        color: Colors.blue[100],
        padding: const EdgeInsets.all(10),
        child: Overlay(
          initialEntries: [OverlayEntry(
            builder: (context) {
              return Center(
                child: Builder(
                  builder: (context) {
                    return ReorderableListView(
                      padding: const EdgeInsets.symmetric(vertical: 10),
                      children: <Widget>[
                        for (int index = 0; index < _items.length; index += 1)
                          Container(
                            key: Key('$index'),
                            height: 60,
                            margin: const EdgeInsets.all(5),
                            color: Colors.blue[400],
                            alignment: Alignment.center,
                            child: Text('Item ${_items[index]}'),
                          ),
                      ],
                      onReorder: (int oldIndex, int newIndex) {
                        setState(() {
                          if (oldIndex < newIndex) {
                            newIndex -= 1;
                          }
                          final int item = _items.removeAt(oldIndex);
                          _items.insert(newIndex, item);
                        });
                      },
                    );
                  }
                ),
              );
            }
          )],
        ),
      ),
    );
  }
}

Really interesting while work on this kind of task. Thanks @Ramji