Flutter Sortable拖放ListView

Jar*_*red 8 listview drag-and-drop flutter flutter-animation

因此,我开始学习Flutter,并想像在材料指南网站上看到的那样使用材料设计拖放列表。

https://storage.googleapis.com/spec-host-backup/mio-design%2Fassets%2F1dtprsH4jZ2nOnjBCJeJXd7n4U-jmWyas%2F03-list-reorder.mp4

到目前为止,我尝试过的所有库看上去都像垃圾。是否有一个我所缺少的良好库或一个Flutter原生窗口小部件?

And*_*sky 11

我尝试过flutter_reorderable_listdragable_flutter_list但它们都没有正常工作 - 在拖动过程中出现了一些不需要的工件。所以我试图制定自己的解决方案:

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,
          )
        ],
      );
    },
  );
}
Run Code Online (Sandbox Code Playgroud)

我想,这不是最好的解决方案,我可能会进一步改变它,但现在它工作得很好


jam*_*lin 7

Flutter本身提供了(Material)ReorderableListView类


Feu*_*Feu 5

检查knopp / flutter_reorderable_list。它就是这样做的。它真的很流畅,并且没有性能问题,能够处理数千个项目。

但是,它的实现并不像通常的flutter小部件那样容易。

如果您为此感到困惑,建议您使用我创建的小部件将flutter/ReorderableListViews 移植到knopp/ReorderableList

这个小部件非常易于使用,但是却没有提供相同的灵活性,并且与一起使用时children List,它的扩展性不如原始版本。

这是ReorderableListSimple代码,这是演示


Cop*_*oad 5

在此处输入图片说明

您可以使用本机flutter小部件ReorderableListView来实现它,下面是执行此操作的示例。

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(() {});
      },
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 长按重新排序 (3认同)
  • 请注意,长按重新排序绝对违反了材料设计规范,不应该在 Android 上使用(不知道 iOS 上如何)。据我所知,到目前为止,还没有办法提供可以通过“ReorderableListView”简单抓取的句柄 (2认同)
  • @A.Bourgoin 这是不正确的,请检查 https://material.io/components/lists#behavior“要重新排序列表项,请拖动它。”。“长按”是针对内容块而不是列表(例如,正常拖动意味着选择的编辑器)或具有清晰拖动手柄的元素来描述的。 (2认同)