Flutter ListView 拖拽排序了解一下

前面我们对于 ListView 的操作讲过 Flutter 滑动删除最佳实践,那现在我们来了解一下 ListView 的拖拽排序。

效果如下:

ReorderableListView

想要达到如上效果,需使用该类,官网简介:

A list whose items the user can interactively reorder by dragging. This class is appropriate for views with a small number of children because constructing the List[1] requires doing work for every child that could possibly be displayed in the list view instead of just those children that are actually visible. All children[2] must have a key.

简单翻译如下:

用户可以通过拖动来重新排序的列表。 该类适用于少量 children 的页面,因为构造列表需要为每一个 children 执行操作,而不只是可见的 children。 所有的 children 都必须有一个 key。

构造函数

按照惯例,查看构造函数:

ReorderableListView({
  this.header,
  @required this.children,
  @required this.onReorder,
  this.scrollDirection = Axis.vertical,
  this.padding,
  this.reverse = false,
}) : assert(scrollDirection != null),
assert(onReorder != null),
assert(children != null),
assert(
  children.every((Widget w) => w.key != null),
  'All children of this widget must have a key.',
);

了解一下各个参数:

•header:是一个不参与拖动排序的 Widget•children:不用多说,列表项•onReorder:见名知意,重新排序后的回调•scrollDirection:方向

剩下两个就不多说了,都应该了解。

简单使用

既然看完了构造函数,那我们就可以分分钟写一个 Demo 出来:

class _ReorderableListViewPageState extends State<ReorderableListViewPage> {
  List<Color> _data = [
    Colors.blue,
    Colors.pinkAccent,
    Colors.deepPurple,
    Colors.orangeAccent
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ReorderableListViewPage'),
      ),
      body: ReorderableListView(
          header: Container(
            height: 50,
          ),
          children: _data
              .map((s) => Card(
                    color: s,
                    key: Key(s.toString()),
                    child: Container(
                      width: 300,
                      height: 100,
                    ),
                  ))
              .toList(),
          onReorder: (int oldIndex, int newIndex) {
            print("$oldIndex --- $newIndex");
          }),
    );
  }
}

1.首先我们定义好一组颜色的列表2.然后在 build 方法中返回 ReorderableListView3.ReorderableListView 中的 children 为用颜色定义好的 Card4.在 onReorder 回调中打印两个参数 oldIndex & newIndex

运行一下,看一下打印的 log:

可以看到确实是能打印出新旧两个 index, 但是这里有一个很明显的问题,

我们大家都知道数组的下标是从 0 开始,可以看到 第一次是 从 0 到 3,第二次是从 0 到 4,

但是讲道理明明应该是 从 0 到 2,从 0 到 3。

那为什么我前两次移动后的 newIndex 都 +1 了呢?

我们这里也不去深究,

既然我们要移动,那肯定也会对源数据进行操作,不然移动也都是假的。

所以,基于这样的一个 newIndex,我们只需要这样:

setState(() {
  if(oldIndex < newIndex) {
      newIndex -= 1;    
  }

  var temp = _data.removeAt(oldIndex);
  _data.insert(newIndex, temp);
});

1.先判断是向上还是向下拖拽2.如果是向下拖拽,那么 newIndex 会多加一个,我们把它减掉3.然后我们删除旧数据并保存它4.最后在新的 index 上插入

ListView 的拖拽排序和删除

既然前面说到了 ListView 的删除,那这里也必须把它俩组合起来了:

其实代码非常简单,当然这也得益于 Flutter 一切皆 Widget,我们只需要在 Card 上包裹一个 Dismissible 就ok了:

children: _data
  .map((s) => Dismissible(
    key: Key("dismiss $s"),
    child: Card(
      color: s,
      key: Key(s.toString()),
      child: Container(
        width: 300,
        height: 100,
      ),
    ),
  ))
  .toList(),

总结

在 Flutter 当中,我们可以封装很多的 Widget 来为我们日后的开发来节省时间,

当然,也不要忘记 Flutter 当中的 Widget 测试

References

[1] List: https://api.flutter.dev/flutter/dart-core/List-class.html [2] children: https://api.flutter.dev/flutter/material/ReorderableListView/children.html

本文分享自微信公众号 - Flutter笔记(Flutter_Note)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java后端技术栈cwnait

浅谈几种设计模式

策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

7540
来自专栏landv

《挑战30天C++入门极限》C++的iostream标准库介绍(1)

  我们所熟悉的输入输出操作分别是由istream(输入流)和ostream(输出流)这两个类提供的,为了允许双向的输入/输出,由istream和ostre...

6810
来自专栏code秘密花园

Hybrid App 应用开发中 9 个必备知识点复习

我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 《Hybrid APP 混合应用专题》 主题的第二期和第三期的合集。

12230
来自专栏GitHubDaily

分享集锦:设计模式讲解、Node.js 教程、Swift UI、Java 开发

最近这段时间比较忙,产出内容频率低了一些,等这周忙完后,后面会抽空写几篇 GitHub 专题文章,敬请期待。

10520
来自专栏iOS开发干货分享

腾讯社招iOS面试记录

毕业好几年了,上周发送了简历给腾讯,参加了腾讯面试。具体部门这边就不说了。这次面试还是收获到了很多。

27700
来自专栏搜狗测试

【总结】ios端被忽略的文件容错测试

iphone沙盒模型的有四个文件夹:分别是 documents,Library,tmp,app包。手动保存的文件在documents文件里,NSUserdef...

11350
来自专栏matlab爱好者

纯代码实现matlabのGUI界面搭建

图形用户界面 (Graphical User Interface,简称 GUI),是有别于纯代码执行,GUI能够繁琐的代码浓缩到一块简洁的界面上,用户只需要输输...

15410
来自专栏安卓开发干货分享

Flutter + MVP +Kotlin 实战!

Kotlin,由 JetBrains 于 2011.07 推出,一款面向 JVM 在 Java 虚拟机上运行的静态类型编程语言。

21000
来自专栏欧阳大哥的轮子

UILabel显示定时器文本的跳动问题解决方案

上面的gif图会发现在显示验证码计数时出现跳动和闪烁的问题。目前大多数用来实现定时器显示的控件都是UILabel。

13720
来自专栏华章科技

为什么Flutter是跨平台开发的终极之选

导读:近日,谷歌开发者官方宣布,Flutter 1.7 正式发布,包含了对 AndroidX 的支持。

32320

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励