前言

今天是复工的第一天,现在还是不太能接受假期就这么结束了,就当是一场梦,醒了很久还是很不能接受;

回正题,

这篇的主题在Flutter中实现拖拽排序可以怎么做;

当然,flutter 中本身就带有 ReorderableListView 这个控件,不过如果需要对 GridView、瀑布流这种来做一个拖拽排序的话,flutter本身并没有类似 ReorderableGridView 这种东西;

这时候就到了万能的 pub.dev 上场的时候了

reorderable 介绍

目前在pub上搜索reorder这个关键词,相关部分中,like最多的就是 [reorderable],

按照其描述,提供了多种类型的可排序组件,

其中有一个ReorderableWrap 就是我需要的效果……额,应该说一部分;也就是这次要说的内容:长按拖拽排序;

reorderable 的实现原理

还是老样子,先带着问题分析过程:

先对其实现过程提出这么几个问题:

  • 长按之后会在原地留下个虚影,这个是怎么实现的;
  • 移动到其他Item的时候,是怎么判断插入到目标Item的前面还是后面的?
  • 排序之后,其他Item依次往后或者往前移动,这个效果是怎么实现的?

要解决这些问题,首先要看下基本机构和原理:

要了解基本机构,就要来到build方法:

build 方法快速一览:

build方法最终返回的东西,其实默认是一个Wrap,也就是那个defaultBuildItemContainer构造出来的,所以可疑的部分来到了wrappedChildren:

image.png

而这个wrappedChildren,仅仅是对child包了一层?????看来核心是这个_wrap 方法?

image.png

不过值得警觉的是,这里好像,做了个排序,先记一下:

image.png

那么来看下这个值得怀疑的_wrap方法:

_wrap 方法快速一览

_wrap 方法挺长的,不过还是先看return 部分;

image.png

_wrap 的 return 这块 ,_buildContainerForMainAxis 方法是返回一个 wrap ,对于了解结构这块,好像意义不大;

_includeMovedAdjacentChildIfNeeded 有点意思,是根据 _ghostDisplayIndex 和 _currentDisplayIndex ,以及传入的 childDisplayIndex ,对构造的 dragTarget 进行一个改造,判断是否需要添加 disappearingPreChild ,以及添加的顺序,这里先放一下,毕竟这几个参数是干啥用的,也不知道;

下面这个 dragTarget ,就是Reorderables实现的核心点了;

image.png

dragTarget 是一个stack,由三层组成:containedDraggable.builder ; 位置在left、top的一半大小的preDragTarget,以及在right、bottom,同样一半大小的nextDragTrget;

其实应该有人看出来了,不止这里,前面也多次出现过 Draggable 和 DragTarget 相关的部分的词语;

所以其实核心技术点就是Draggable跟DragTarget的组合使用;preDragTarget 跟 nextDragTarget 这两块也确实的出现了DragTarget

image.png

而上面提到的 containedDraggable.builder ,其实就是Draggable:

image.png image.png

所以结构也很清楚了,总结一下的话就是

在Wrap的容器内有数个Item,每个Item都是一个Stack,里面除了item的内容外,还分别在两边各放一半的SizeBox来当作DragTarget;

基本结构了解完,貌似部分问题其实就有答案了……

长按留下的虚影的实现方式:

Draggable提供了 childWhenDragging 方法,以供在拖拽的时候在原地留个占位;

那么将这个占位做个半透明处理,那不就是虚影了?

image.png

Item拖拽到指定位置后,移动位置的判断方式:

正如上面在基本结构分析中所述,每个Item,其实都包含了两个DragTarget,各占一半;拖拽到哪个DragTarget,哪个DragTarget做出响应即可:

image.png

依次移动动画的实现方式:

知道了位置之后,插入的动画怎么实现,就要看这个 onWillAccept方法,它是怎么处理响应的:

首先是对一些参数进行计算,做一些边界判断,以及判断滑动响应的Item是自己本身对应的,那就不做响应,之类的东西:

image.png

下面这块就是真正去响应操作,触发动画的部分了:

image.png

在这里触发一次 setState ,修改 _nextDisplayIndex , 触发_requestAnimationToNextIndex

参数这块先不管,setState总体完成后再看看具体作用,那么看下这个_requestAnimationToNextIndex 方法:

image.png

这里的作用就是设置 _ghostDisplayIndex、_currentDisplayIndex 这两个参数的值,并触发了两个AnimationController

话说,这个_ghostDisplayIndex、_currentDisplayIndex , 是不是在哪里见过???

好像,build方法中,会根据_currentDisplayIndex 做个排序?

那么setState的作用就清楚了,直接排序,并将已经处于 childWhenDragging 状态的Item 插入过去,这样,虚影就显示到目标位置了;

而这两个AnimationController的作用,就要看其调用位置了

在前面的贴图中,可以看到,很多部分,Item的显示内容,都会包一层东西,比如说 childWhenDragging 那块,child是一个 _makeAppearingWidget ,builder方法也是,会往List中加入 _makeDisappearingWidget 构造出的widget;

总结一下的话,就是会往目标位置跟拖动Item中的Item放入_makeAppearingWidget跟_makeDisappearingWidget包裹的Item

其实这两个Controller就是控制这两个Widget的,一个负责处理添加的时候后移操作动画,一个负责处理移走的前移操作动画;

image.png

而其实现方式也简单:

image.png

没错,用SizeTranstion,通过动画改变Item大小,把后面的Item挤过去……

总结一下:

setState 后build方法将要拖拽的Item移动到目标位置,这时候Item本身的大小为0,随着动画的播放,SizeTranstion 逐渐改变Item的大小,后面的部分就这么给挤过去了……(这方法我当时确实没想到,还可以这么玩~~~)

当然会对特殊情况做个小处理:

image.png

当发生跨行的时候,让跨行的第一个Item也执行由小变大的动画;

结语

这作者的操作确实让人开眼界,我当时还以为要通过OverLay之类的东西来搞,没想到其实实现方式没必要那么复杂,这不挺简单的嘛:

国际惯例,效果图:

在这里插入图片描述

下面就是搞搞这个的改造,加入那个文件夹功能;

总结

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐