To add drag-and-drop functionality to a GridView, wrap your grid in a ReorderableBuilder.
Key Requirements:
- Unique Keys: Every child within the
GridView must have a unique Key. - onReorder Callback: You must implement the
onReorder callback to update your underlying data source. The callback provides a ReorderedListFunction, which you pass your list to in order to receive the new reordered list. - ScrollController: If your
GridView is scrollable, you must assign the same ScrollController instance to both the ReorderableBuilder and the GridView itself.
Note on Scrolling: If the ReorderableBuilder is inside another scrollable widget, do not manually assign a ScrollController; it will automatically look up the existing one in the context. Manually assigning one in a nested scrollable context can break drag-and-drop functionality.
import 'package:flutter/material.dart';
import 'package:flutter_reorderable_grid_view/widgets/widgets.dart';
// ... inside your State class ...
final _scrollController = ScrollController();
var _fruits = <String>["apple", "banana", "strawberry"];
@override
Widget build(BuildContext context) {
final generatedChildren = List.generate(
_fruits.length,
(index) => Container(
key: Key(_fruits[index]), // Unique key is required
color: Colors.lightBlue,
child: Text(_fruits[index]),
),
);
return Scaffold(
body: ReorderableBuilder(
children: generatedChildren,
scrollController: _scrollController,
onReorder: (ReorderedListFunction reorderedListFunction) {
setState(() {
// Update your data source using the returned list
_fruits = reorderedListFunction(_fruits) as List<String>;
});
},
builder: (children) {
return GridView(
controller: _scrollController, // Must match ReorderableBuilder controller
children: children,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
);
},
),
);
}