Flutter 小技巧之滑动控件即将“抛弃” shrinkWrap 属性

相信对于 Flutter 开发的大家来说, ListView 的 shrinkWrap 配置都不会陌生,如下图所示,每当遇到类似的 unbounded error 的时候,总会有第一反应就是给 ListView 加上 shrinkWrap: true 就可以解决问题,那为什么现在会说 shrinkWrap 即将被“抛弃”呢?

其实说完全“抛弃”也不大严谨,从目前官方的规划来看, shrinkWrap 配置将从滑动控件里弃用,因为团队觉得现阶段的开发人员大多数时候不知道它的实际含义,只是单纯使用它解决问题,在使用过程中容易出现错误的性能损耗而不自知

当然,这个提议并不是说完全废除 shrinkWrap 的支持,而且类似通过全新的 Widget 来替代,用更形象的命名,例如 NonLazyListView 等。

目前这个提议的等级是 P1 ,所以如果不意外的话,它的推进会很快

那么 shrinkWrap 为什么会带来性能问题?它常用在什么场景?为什么会需要被提高到 P1 来进行调整?

首先我们需要简单理解 Flutter 滑动列表的实现和 shrinkWrap 的作用,在《带你了解 Flutter 中的滑动列表实现》里我们介绍过,Flutter 里的滑动列表是由 ViewportScrollable 和相应的 Sliver 三部分组成

ListView 为例,如下图所示是 ListView 滑动过程的变化,其中:

  • 绿色的 Viewport 就是我们看到的列表窗口大小;
  • 紫色部分就是处理手势的 Scrollable,让黄色部分 SliverListViewport 里产生滑动;
  • 黄色的部分就是 SliverList , 当我们滑动时其实就是它在 Viewport 里的位置发生了变化;

所以 ListView 之所以可以“无限”滑动,就是因为首先有一个固定大小「窗口」, 只有在进入和靠近「窗口」的 Item 才会被布局渲染,从而保证了列表的性能。

但是这也带来了一个问题,如下图 1 的代码所示,它就因为 Column 的特性,没办法直接计算得到 Viewport 的大小,所以会抛出错误。

有时候我们会如上图 2 所示,通过给 ListView 加一个 Expanded 来解决,这样 ListView 会充满 Column 的剩余空间,从而得到一个固定的 Viewport 大小。

但是当我们希望此时 ListView 不充满,还可以居中显示的时候,就会采用如上图 3 所示那样,添加一个 shrinkWrap: true

虽然这个例子没有意义,但是它展示了 shrinkWrap 的“主要”场景,另外 shrinkWrap 也常被用于 ListView 嵌套 ListView 这种不规范使用的场景中

shrinkWrap 的实现原理是什么?简单来说,现阶段 shrinkWrap:true 的时候,在滑动控件内部会采用一个特殊的 ShrinkWrappingViewport 「窗口」进行实现。

ShrinkWrappingViewportViewport 的不同之处在于 :

  • Viewport 是填充满主轴方向的大小
  • ShrinkWrappingViewport 是调整自身大小去匹配主轴方向中 Item 的大小,而这种“收缩”的行为成本会变高,因为窗口大小需要通过 child 去“确定”。

例如,如下图所示,在 ListView 里,我们将 itemCount 修改为 400 ,然后打印每个 Item 的 build ,由于 shrinkWrap 的作用,可以看到 400 个 child 都被输出。

同样,在 Inspector 的 Widget Tree 里可以看到 400 个 child 都构建完成,尽管他们还远没有在 ViewPort 展示出来,所以 shrinkWrapListView 失去了懒加载的作用。

相反,如下图代码所示,如果去掉 shrinkWrap ,在 Expand 的作用下 ListView 有了固定大小的 ViewPort ,此时就算是 itemCount 是 400 ,但是也只会根据 ViewPort 构建所需的 19 个 child 。

就算是因为滑动产生变化,正常情况下的 ListView 也保持着「固定」的长度,例如滑动到 160 的 index 的时候,此时开始的 ListTitle 的 index 是 135 ,而不会像 shrinkWrap 一样保持着全员 child 的构建。

如何要深究的话,其中关键点之一就在于 updateOutOfBandData 方法实现的不同,在普通 Viewport 里, updateOutOfBandData 方法只是用于计算 maxScrollExtent ,而如下图 1 所示,ShrinkWrappingViewport 里会对每个 child 的 maxPaintExtent 进行累计。

累计之后的得到的 _shrinkWrapExtent 最终会转化为 ShrinkWrappingViewport 自己的 size ,这也是 ShrinkWrappingViewport 为什么可以根据 child 调整「窗口」大小的原因。

所以,在此之前可能开发者经常通过简单的 shrinkWrap 来解决问题,而比较少思考 shrinkWrap 的实现原理,或者说缺乏理解它的作用,从而带来了一些隐形的性能问题而不自知,所以这也是为什么这次会有该调整的原因:

shrinkWrap 迁移到全新控件可以更直观让大家理解其作用,而其实大部分使用 shrinkWrap 的场景可以被其他实现替代。

  • 例如前面提到的 ListView 嵌套 ListView 的场景,与其对通过配置 shrinkWrap 来实现,不如通过 CustomScrollView 结合不同 SliverList 或者其他 Sliver 组建完成组合。

  • 而如果 child 并不多,其实也可以直接通过 SingleChildScrollView + Column 来实现,它在一定程度上效果和 shrinkWrap 类似。

所以,到这里你应该知道了 shrinkWrap 的实现逻辑和作用,其实本次主要也是想通过这个 new feature 变动,带大家重新认识下 shrinkWrap因为接下来,它就不再叫 shrinkWrap 了,或者你以后也应该很少用到它

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/29624.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot进阶(55):SpringBoot之集成MongoDB及实战使用 | 超级详细,建议收藏

1. 前言🔥 前几期我们有介绍Mysql、Redis等数据库介绍及实战演示,对基本的数据存放有很好的共性,但是如果说遇到大面积的xml、Json、bson等格式文档数据存放,以上数据库并非是最优选择,最优选择是Mongodb数据库。 那么…

AI时代图像安全“黑科技”如何助力人工智能与科技发展?

〇、前言 7月7日下午,2023世界人工智能大会(WAIC)“聚焦大模型时代AIGC新浪潮—可信AI”论坛在上海世博中心红厅举行。人工智能等技术前沿领域的著名专家与学者、投资人和领军创业者汇聚一堂,共同探索中国科技创新的驱动力量。 在…

机器学习(十六):决策树

全文共18000余字,预计阅读时间约36~60分钟 | 满满干货,建议收藏! 一、介绍 树模型是目前机器学习领域最为重要的模型之一,同时它也是集成学习中最常用的基础分类器。 与线性回归、逻辑回归等算法不同,树模型并不只是…

【电路效应】信号处理和通信系统模型中的模拟电路效应研究(SimulinkMatlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码、Simulink仿真实现 💥1 概述 在信号处理和通信系统模型中,模拟电路效应研究是指考虑到实际电路的特性对信号进行建模和分析的过程。模拟电路效应…

docker k8s

Docker docker到底与一般的虚拟机有什么不同呢? 我们知道一般的linux系统即GNU/Linux系统包括两个部分,linux系统内核GNU提供的大量自由软件,而centos就是众多GNU/Linux系统中的一个。 虚拟机会在宿主机上虚拟出一个完整的操作系统与宿主机完…

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

文章目录 ⭐前言⭐利用inscode免费开放资源💖 在inscode搭建vue3tsant项目💖 调整配置💖 antd 国际化配置💖 用户store💖 路由权限💖 预览 ⭐结束 ⭐前言 大家好,我是yma16,本文分享…

Golang跨平台UI框架之Wails(二)

上一篇文章我们讲解了如何简单创建一个 wails 的项目,但是现在有很多前端框架我们可以选择,比如: AngularVueSvelteReactLitVanilla各个都是时代的弄潮儿,就看哪一个适合你了,后续的系列都是以Angular为例。 1. 创建Angular模板项目 由于 wails 是没有官方支持Angular的…

SignalTap II 软件使用步骤

文章目录 前言一、SignalTap II是什么?二、使用步骤三、总结四、参考资料 前言 环境: 1、Quartus18.1 2、板子型号:原子哥开拓者2(EP4CE10F17C8) 要求: 能够使用SignalTap II进行片上调试。 一、SignalTap II是什么? S…

vue3+vite+ts+vant 开发浙里办H5应用流程和注意事项

vue3vitets 开发浙里办H5应用流程和注意事项 最近有个项目是要开发到浙里办的一个H5项目,记录一些问题; 浙里办irs系统内node版本和npm版本如下建议切到他们的版本再进行开发这样问题少一点 1.因为浙里办有自己的irs系统 需要吧前端整体的代码传上去 除了 打包后的dist 和 no…

4.CSS(一)

目录 一、CSS简介 二、CSS基础选择器 (一)标签选择器 (二)类选择器 类选择器-多类名 (三)id选择器 (四)通配符选择器 (五)总结 三、CSS字体属性 &…

VSCode种git rebase分支冲突解决无法继续rebase

情景: 常规来说我们git开分支开发完新功能之后,提交之前rebase dev分支,然后合并到dev上算是开发完成。 问题还原: 在开发完之后执行如下指令: 1.执行变基操作:git rebase dev。 //这一步出现冲突vscode上…

重磅升级 | 睿士主机威胁溯源系统全新升级,助力用户2023网络攻防演练

攻防演练至今已走过7个年头,逐渐成为网络安全防御体系中至关重要的一环。随着攻防演练对抗水平不断升级,攻击手段愈发隐蔽,攻击自动化程度逐步提高,技术储备也越来越有针对性,从广撒网到精准打击,这些都给蓝…