'Reorder items in SliverList in Flutter with Drag & Drop

I´m using a SliverList with SliverChildBuilderDelegate to generate the list items on the fly. Now I´m trying to allow the user to reorder the list items via drag and drop over a handle-icon on each item in a row.

I´ve tried different things (like Draggable Widget) but I haven´t found a solution so far. Has anyone already used drag & drop reordering with a SliverList Widget and can give me a hint?

Using ReorderableListView Widget is not possible, cause mixing a ListView to a SliverList. And I want to use the SliverAppBar to allow a fade-out-on-scroll effect as you can see here: https://medium.com/flutter-io/slivers-demystified-6ff68ab0296f

Here´s the structure of my SliverList:

return Scaffold(
  body: RefreshIndicator(
    ...
    child: CustomScrollView(
      ...
      slivers: <Widget>[
        SliverAppBar(...),
        SliverList(
          delegate: SliverChildBuilderDelegate(...),
        )
        ...

Thanks in advance & best, Michael



Solution 1:[1]

Check out this reorderables package on pub. It recently added support to SliverList.

Screenshot here: ReorderableSliverList

The example has sliver list and app bar and shows what you are looking for. Just replace SliverList and SliverChildBuilderDelegate in your code with the counter parts from the package.

class _SliverExampleState extends State<SliverExample> {
  List<Widget> _rows;

  @override
  void initState() {
    super.initState();
    _rows = List<Widget>.generate(50,
        (int index) => Text('This is sliver child $index', textScaleFactor: 2)
    );
  }

  @override
  Widget build(BuildContext context) {
    void _onReorder(int oldIndex, int newIndex) {
      setState(() {
        Widget row = _rows.removeAt(oldIndex);
        _rows.insert(newIndex, row);
      });
    }
    ScrollController _scrollController = PrimaryScrollController.of(context) ?? ScrollController();

    return CustomScrollView(
      // a ScrollController must be included in CustomScrollView, otherwise
      // ReorderableSliverList wouldn't work
      controller: _scrollController,
      slivers: <Widget>[
        SliverAppBar(
          expandedHeight: 210.0,
          flexibleSpace: FlexibleSpaceBar(
            title: Text('ReorderableSliverList'),
            background: Image.network(
              'https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Yushan'
                '_main_east_peak%2BHuang_Chung_Yu%E9%BB%83%E4%B8%AD%E4%BD%91%2B'
                '9030.png/640px-Yushan_main_east_peak%2BHuang_Chung_Yu%E9%BB%83'
                '%E4%B8%AD%E4%BD%91%2B9030.png'),
          ),
        ),
        ReorderableSliverList(
          delegate: ReorderableSliverChildListDelegate(_rows),
          // or use ReorderableSliverChildBuilderDelegate if needed
//          delegate: ReorderableSliverChildBuilderDelegate(
//            (BuildContext context, int index) => _rows[index],
//            childCount: _rows.length
//          ),
          onReorder: _onReorder,
        )
      ],
    );
  }
}

Solution 2:[2]

You might check out flutter_reorderable_list. I've not yet tried it and am currently in the process of rolling my own, but it looks decent and the example uses a CustomScrollView with SliverList.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hansheng
Solution 2 Dave