Flutter Sortable Drag And Drop ListView

后端 未结 5 1054
旧巷少年郎
旧巷少年郎 2020-12-10 04:06

So I\'m starting to learn Flutter and would like to use a material design drag and drop list just like the one seen on the material guidelines website.

https://stora

相关标签:
5条回答
  • 2020-12-10 04:19

    I've tried flutter_reorderable_list and dragable_flutter_list but none of them worked properly - there was some unwanted artifacts during dragging. So I've tried to make own solution:

    ListView.builder(
      itemBuilder: (context, index) => buildRow(index),
      itemCount: trackList.length,
    ),
    
    Widget buildRow(int index) {
      final track = trackList[index];
      ListTile tile = ListTile(
        title: Text('${track.getName()}'),
      );
      Draggable draggable = LongPressDraggable<Track>(
        data: track,
        axis: Axis.vertical,
        maxSimultaneousDrags: 1,
        child: tile,
        childWhenDragging: Opacity(
          opacity: 0.5,
          child: tile,
        ),
        feedback: Material(
          child: ConstrainedBox(
            constraints:
                BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
            child: tile,
          ),
          elevation: 4.0,
        ),
      );
    
      return DragTarget<Track>(
        onWillAccept: (track) {
          return trackList.indexOf(track) != index;
        },
        onAccept: (track) {
          setState(() {
            int currentIndex = trackList.indexOf(track);
            trackList.remove(track);
            trackList.insert(currentIndex > index ? index : index - 1, track);
          });
        },
        builder: (BuildContext context, List<Track> candidateData,
            List<dynamic> rejectedData) {
          return Column(
            children: <Widget>[
              AnimatedSize(
                duration: Duration(milliseconds: 100),
                vsync: this,
                child: candidateData.isEmpty
                    ? Container()
                    : Opacity(
                        opacity: 0.0,
                        child: tile,
                      ),
              ),
              Card(
                child: candidateData.isEmpty ? draggable : tile,
              )
            ],
          );
        },
      );
    }
    

    I guess, this is not the best solution, and I'm maybe will change it further, but for now it works quite well

    0 讨论(0)
  • 2020-12-10 04:20

    Check knopp/flutter_reorderable_list. It accomplishes just that. It's really smooth and it's got no performance issues, being able to handle thousands of items.

    However, it's implementation is not easy as usual flutter widgets.

    If you struggle with that, I'd recommend you to use a widget I created to port flutter/ReorderableListViews to the knopp/ReorderableList.

    This widget makes it really easy to use, however it doesn't provide the same flexibility, and as it works with a children List, it's not as scalable as the original.

    Here's the code for ReorderableListSimple and this is the demo.

    0 讨论(0)
  • 2020-12-10 04:23

    Flutter team introduced ReorderableListView widget.

    ReorderableListView(
          children: <Widget>[
            for (var item in appState.menuButtons) 
            Text('data')              
    
          ],
        )
    
    0 讨论(0)
  • 2020-12-10 04:38

    You can use native flutter widget, ReorderableListView to achieve it, here is the example of doing it.

    List<String> _list = ["Apple", "Ball", "Cat", "Dog", "Elephant"];
    
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(),
        body: ReorderableListView(
          children: _list.map((item) => ListTile(key: Key("${item}"), title: Text("${item}"), trailing: Icon(Icons.menu),)).toList(),
          onReorder: (int start, int current) {
            // dragging from top to bottom
            if (start < current) {
              int end = current - 1;
              String startItem = _list[start];
              int i = 0;
              int local = start;
              do {
                _list[local] = _list[++local];
                i++;
              } while (i < end - start);
              _list[end] = startItem;
            }
            // dragging from bottom to top
            else if (start > current) {
              String startItem = _list[start];
              for (int i = start; i > current; i--) {
                _list[i] = _list[i - 1];
              }
              _list[current] = startItem;
            }
            setState(() {});
          },
        ),
      );
    }
    
    0 讨论(0)
  • 2020-12-10 04:38

    Flutter itself provides a (Material) ReorderableListView class.

    0 讨论(0)
提交回复
热议问题