为了账号安全,请及时绑定邮箱和手机立即绑定

Flutter | WReorderList 一个可以指定两个item互换位置的组件

标签:
WebApp

最近遇到个需求,要求在一个 ListView 里面能互换两个 item 的位置,这样:

https://img1.sycdn.imooc.com//5da548aa00010c4904590649.jpg

于是,就有了现在的这个 WReorderList

WReorderList

功能就不用多说了,可以随意替换两个 item 的位置。

构造函数及其用法

还是按照老规矩,先来看一下构造函数:

WReorderList({

  Key key,

  @required this.children,

  @required this.onIndexChanged,

  this.duration = const Duration(milliseconds: 500)

}) : super(key: key);

一共四个参数:

1.key:不用多说2.children:子组件集合3.onIndexChanged:当两个位置变化之后的回调,要更改您自己的数据源4.duration:动画时间

怎么用就很简单了:

WReorderList(

  key: key,

  children: children,

  onIndexChanged: (a, b) {

    setState(() {

      var temp = _colors[a];

      _colors[a] = _colors[b];

      _colors[b] = temp;

    });

  },

),

组件用上了, 那如何交换位置呢?

有两种方法:

1.给 WReorderList 设置一个 GlobalKey,然后 key.currentState.swap(0, 1) 就OK了2.通过 WReorderList.of(context) 方法获取到 state,然后再调用 swap 方法就好了。

WReorderList 原理解析

分析原理

首先从技术角度分析一下:

1.怎么交换两个 item 位置?2.如何获取到需要交换的两个 item 的组件3.交换过程中两个 item 原来的位置上要被空白占用?

怎么交换两个 item 位置

这里我原本预想了好几种方案:

1.弹出一个Overlay,在 Overlay 上做动画2.弹出一个 PopupRoute,用 Hero 动画3.染出一个 PopupRoute,在上面做动画

第一种方案被否决了,因为我 Overlay 用的不是很多。

第二种我试了一下,发现 Hero 不能用,所以也否了。

那就只剩第三种了,我试了一下用 AnimatedPositioned,发现是可以的,那就决定是他了。

如何获取到需要交换的两个 item 的组件

这个我原本也想过用 GlobalKey,但是在列表中有一大堆的 GlobalKey 又不好,

所以我定义了一个类,该类如下:

class WReorderData {

  Widget widget;

  BuildContext context;

  double height;


  WReorderData(this.widget);

}

在用户传进来 children 以后,就用该类包住,获取到他的widget。

并且在 build 的时候用 Builder 包裹住就可以获取到当前这个 widget 的 context了。

就能获取到需要交换的两个 item 的位置。

交换过程中两个 item 原来的位置上要被空白占用?

可以看到最开始的效果中,交换过程中是被空白给占用了的,那这个高度如何获取?

我查了一下资料,发现这种是个有效的方法:

在 build 的时候加上一个 Future.delayed,100毫秒之后用当前 context 获取高度,这样就ok了。

代码如下:

Builder(builder: (context) {

  Future.delayed(Duration(milliseconds: 100), () {

    data[index].context = context;

    data[index].height = context.size.height;

  });

  return swapIndex.contains(index)

    ? Container(height: data[index].height)

    : data[index].widget;

});

总结

最近通过PopupRoute 已经定义了两个组件了,感觉还是很有用的。

有个需要注意的点是:使用 WReorderList.of(context) 方法来获取 State 的话,一定要在子组件中,否则会找不到 state!!!


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
30
获赞与收藏
45

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消