简体   繁体   English

Flutter Sortable拖放ListView

[英]Flutter Sortable Drag And Drop ListView

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. 因此,我开始学习Flutter,并想像在材料指南网站上看到的那样使用材料设计拖放列表。

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

All of the libraries I have tried out so far look like garbage compared to that. 到目前为止,我尝试过的所有库看上去都像垃圾。 Is there a good library for this that I am missing or a native Flutter widget? 是否有一个我所缺少的良好库或一个Flutter原生窗口小部件?

Flutter本身提供了(Material) ReorderableListView类

Check knopp/flutter_reorderable_list . 检查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. 但是,它的实现并不像通常的flutter小部件那样容易。

If you struggle with that, I'd recommend you to use a widget I created to port flutter/ReorderableListView s to the knopp/ReorderableList . 如果您flutter/ReorderableListView ,建议您使用我创建的小部件将flutter/ReorderableListViewknopp/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. 这个小部件非常易于使用,但是却没有提供相同的灵活性,并且与children List ,它的伸缩性不如原始的。

Here's the code for ReorderableListSimple and this is the demo . 这是ReorderableListSimple代码 ,这是演示

I've tried flutter_reorderable_list and dragable_flutter_list but none of them worked properly - there was some unwanted artifacts during dragging. 我已经尝试了flutter_reorderable_listdragable_flutter_list,但是它们都无法正常工作-拖动过程中出现了一些不需要的工件。 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 我猜这不是最好的解决方案,我可能会对其进行进一步更改,但目前效果很好

在此处输入图片说明

You can use native flutter widget, ReorderableListView to achieve it, here is the example of doing it. 您可以使用本机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(() {});
      },
    ),
  );
}

Flutter team introduced ReorderableListView widget. Flutter团队引入了ReorderableListView小部件。

ReorderableListView(
      children: <Widget>[
        for (var item in appState.menuButtons) 
        Text('data')              

      ],
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM