当前位置: 首页 > news >正文

vue 网站开发狗和女人做的网站

vue 网站开发,狗和女人做的网站,微信分销小程序,网页设计师联盟网站怎么作者#xff1a;闲鱼技术-夜澜 背景 目前闲鱼业务中无论是首页还是搜索页都有大量可以落地瀑布流的场景#xff0c;而在Flutter原生中只提供了ListView, GridView#xff0c;无法提供自定义布局的能力。 而在社区中#xff0c;一般瀑布流的解决方案都是基于SliverMultiB…作者闲鱼技术-夜澜 背景 目前闲鱼业务中无论是首页还是搜索页都有大量可以落地瀑布流的场景而在Flutter原生中只提供了ListView, GridView无法提供自定义布局的能力。 而在社区中一般瀑布流的解决方案都是基于SliverMultiBoxAdaptor对其performLayout进行定制主要存在的问题是缺乏复用机制并且在很多情形下容易出现重复布局在线上业务的复杂场景下容易出现帧数偏低的问题, 闪屏的问题。同时对于Child生命周期打点曝光等一系列基础功能的支持还是一片空白的状态。 所以我们迫切需要一个更为通用的可以解决复杂布局过程同时能够对基础能力进行扩充的列表视图解决方案。 Flutter中的列表视图简介 1. Scrollable Scrollable是一个StatefulWidget, 职责是监听用户的手势输入。其State的build方法会返回一个含有Listener和RawGestureDetector的ViewportScrollPosition用于描述其位置信息并在其内部定义了 onStart, onUpdate, onEnd等回调。Scrollable中的每一次滑动的开始到结束都对应于一个Darg对象并且会发送滑动的通知。而Viewport则负责对通知进行监听。 2. Sliver Flutter有两种布局体系 Box, Sliver。在layout的过程中每个Sliver 都接收 SliverConstraints 计算返回一个 SliverGeometry可以类比于RenderBox 接收 BoxConstraints 返回一个 Size。Sliver由Viewport统一来负责进行管理。 3. Viewport A widget that is bigger on the inside. Viewport持有一个或多个Sliver。Scrollable将offset传递给Viewport, 由Viewport决定哪些Sliver应该是Visible。Viewport本质上是一个MultiChildRenderObjectWidget也就是整个滚动视图的主要渲染逻辑都在Viewport中完成。 而在performLayout中_attemptLayout会以center为中心先布局leading方向的child再布局trailing方向的child。其中只有dirty的child会被布局。 do {correction _attemptLayout(mainAxisExtent, crossAxisExtent, offset.pixels centerOffsetAdjustment);if (correction ! 0.0) {offset.correctBy(correction);} else {if (offset.applyContentDimensions(math.min(0.0, _minScrollExtent mainAxisExtent * anchor),math.max(0.0, _maxScrollExtent - mainAxisExtent * (1.0 - anchor)),))break;}count 1; } while (count _maxLayoutCycles); 如果_attemptLayout返回了一个非0的correction, 就会打断当前布局的过程需要对offset进行调整后重新开始布局最多只能连续打断10次(_maxLayoutCycles)。 correction用于调整举个比如targetScrollOffset很远而在scroll的过程中child用完了就需要让Sliver通知Viewport, 同时进行修正。但是Flutter并不是通过不断对child进行layout来改变child位置实现的滑动效果这样的重绘过程显然效率太低显然RenderObject不需要被改变是可以复用的。但是布局一般只发生在添加新child的过程中而滑动效果则发生在paint过程中。 void _paintWithContext(PaintingContext context, Offset offset) {// 重新布局就不需要调整offset了.if (_needsLayout)return;_needsPaint false;paint(context, offset); } Viewport通过PaintingContext间接持有Canvas进行绘制。Offset指笛卡尔坐标系下的坐标与Axis方向无关。绘制时只需改变对应RenderObject的Offset即可实现滚动的效果, 这样就不必重新创建RenderObject。所以我们如果想实现性能较高的列表视图就要尝试去减少重新布局Child。在对Flutter的列表布局有了基本了解后我们再来看瀑布流的实现过程。 瀑布流的实现逻辑 WatetfallFlow的布局过程中需要指定Child的Offset然后对其进行布局。所以需要继承SliverMultiBoxAtaptor依赖于其将SliverConstraints转换为BoxConstraints的能力。我们也可以使用其SliverBoxChildManager, 方便控制Child的懒加载过程。 核心逻辑 在瀑布流中由于同一行列的child大多具有先后关系需要按照顺序来进行布局所以瀑布流相比于GridView更类似于ListView而瀑布流的布局过程也借鉴了ListView。整个瀑布流的布局逻辑围绕三个核心展开: 在滑动的过程中找到其边缘最近的child在其后前进行添加child并对child进行layout.在child离开一定距离后进行GC.保证layout方法被尽可能少的调用. 上文有提过layout会调用performLayout而不能直接进行paint. 其中核心的数据结构是ParentData. ParentData位于Child中Child将其传递给SliverSliver又将其传递至上层其中储存了全部的布局信息在笛卡尔坐标系下。在performLayout中child在调用layout时所使用的布局信息就来自ParentData。在Child的添加过程中用一个Manager存储前后边缘所有Child的ParentData在添加时寻找边缘最靠近可见区域的Child对其ParentData进行设置并替换当前Child. 布局的核心逻辑是对从最开始的Child对应firstIndex到最末的Child对应targetLastIndex进行布局。如果_layoutedChilds中已经有记录则跳过其布局过程。 for (int index firstIndex; index targetLastIndex; index) {final SliverGeometry gridGeometry layout.getGeometryForChildIndex(index);final BoxConstraints childConstraints gridGeometry.getBoxConstraints(constraints);RenderBox child childAfter(trailingChildWithLayout);if (child null || indexOf(child) ! index) {// 重新获取Child.child _createAndLayoutChildIfNeeded(childConstraints, after: trailingChildWithLayout);if (child ! null indexOf(child) index) {_layoutedChilds.add(index);}else if (child null) {// Child已经用尽.break;}} else {if (!_layoutedChilds.contains(index)) {_layoutChildIfNeeded(child, parentUsesSize: true);_layoutedChilds.add(index);}}trailingChildWithLayout child; } 对离开视图的child进行GC同时记得将数组中的child清除. if (firstChild ! null) {// 上一次的最先最末Child.final int oldFirstIndex indexOf(firstChild);final int oldLastIndex indexOf(lastChild);// 前后需要GC的child数量final int leadingGarbage (firstIndex - oldFirstIndex).clamp(0, childCount);final int trailingGarbage targetLastIndex null ? 0 : (oldLastIndex - targetLastIndex).clamp(0, childCount);// GCcollectGarbage(leadingGarbage, trailingGarbage);_layoutedChilds.sort();_layoutedChilds.removeRange(0, leadingGarbage);_layoutedChilds.removeRange(layoutedChilds.length - 1 - trailingGarbage, layoutedChilds.length - 1); } else {collectGarbage(0, 0); } 在开发过程中出现了帧数偏低的问题发现是Child在performLayout的过程中会出现重复布局。解决方法是我们不仅记录leading, trailing边缘的child。而且用对已经layout过的child进行记录粗暴直接但是有效这样做也可以提供单独update单个child的Layout能力。在更新Child的布局时也只需从记录中将对应child移除。 相比于原生视图我们可以通过获取所有Child的ParentData信息可以为上层接口提供实时并且有效的回调.。这样就可以根据每个Child的实时位置来提供生命周期曝光打点的能力。所以可以对每个child的坐标进行监听从而获得精准的曝光信息。 从瀑布流到容器 在瀑布流的开发过程中也暴露出了一些设计上的问题。 比如瀑布流的具体渲染逻辑都在RenderObject中进行太过底层显然是不利于业务方根据业务进行定制。 又比如由于没有复用的机制在视图层级较为复杂时帧数会由于重复渲染而不可避免的降低。 借鉴native思路重新设计后将整体容器分为3个部分进行设计。 delegate 主要管理child生命周期并响应手势由于我们可以得到每个可见Child的parentData属性所以可在滚动时进行实时的通知。从而对每个Child的位置监听从开始创建进入缓冲区到从缓冲区进入可见区域。手势则来自于顶层的Scrollable。 layout 主要负责布局所有的Child。将具体的布局逻辑抽离出类似于iOS中的UICollectionViewLayout。但是在开发过程中也出现了一些问题原因主要来自于Flutter特殊的信息传递方式就是我们不能采用native的方式一次性计算出所有child的布局。因为RenderBox需要接收一个BoxConstraints才能返回一个size。 reuser reuser则在RenderObject层面对Child进行基于类型的复用并实现局部更新的操作。需要将SliverMultiBoxAdaptor和其Element拷贝一份进行重写改变其mount的逻辑方案还在探索和调研之中希望能在后续的文章中和大家见面 性能数据 应用于主搜索页进行自动化测试先前在54.7帧左右换用瀑布流后为56.2大概提升了1.5帧。 内存上则有略微的升高情况。 展望 目前Flutter的列表视图中仍然有很多问题需要处理比如瀑布流中scrollTo(int index)的能力还无法实现内存的使用情况等和原生相比仍然有不小的差距, 对于Flutter侧的复用的稳定性和兼容性上还存在问题闲鱼在Flutter化上还有很多路要走。 PS0: 文中代码基于Flutter 1.12.13。 PS1: 文中譬如Viewport既代指Widget本身, 又代指其对应的RenderObject。 PS2: 文中涉及到的代码经过删改, 仅供参考。 原文链接https://developer.aliyun.com/article/767965?utm_contentg_1000168249 本文为阿里云原创内容未经允许不得转载。
http://www.zqtcl.cn/news/49242/

相关文章:

  • 网站开发详细设计wordpress 注册 登录
  • 衡器行业网站建设模板建设银行企业网站打不开
  • 彩票网站开发制作网站硬件防火墙
  • 鼎成中考开卷通有关网站做的电子书wordpress首页内容怎么修改
  • 十大购物网站北京做网站找哪家好
  • 网站建设的地方网站模板设计
  • 百度网站怎么优化排名气象网站建设的自查报告
  • 网站开发vue青岛公司的网站设计
  • 网站建设怎么自学普通网站 用多说
  • 网站开发前台实训做旅游网站需要什么
  • t恤在线制作网站公司网站开发文档
  • 网站设置flash插件wordpress去标题版权
  • 学校校园网站建设服务辽宁建设工程信息网查
  • 朵朵软件网站建设培训课程
  • 做网站需要交钱吗附近学电脑培训班
  • 域名有了怎么建网站火车头wordpress 4.7
  • 网站建设格局wordpress打开图片预览代码
  • 怎么建设像天猫的网站网页制作与网站建设宝典 第2版
  • 直接做海报的网站音乐视频怎么做mp3下载网站
  • 一流学科建设专题网站小规模注册公司流程和费用
  • 肇庆建设工程备案的网站润商网站建设服务
  • 网站开发团队配置旧金山网站建设
  • 域名大全百家号优化上首页
  • 襄樊网站建设公司石家庄做网站时光
  • 二手网站建设重庆搜索引擎推广
  • 做内网网站邢台做网站推广的公司
  • 交通建设集团网站做网站制作外包
  • 网站制作 流程新发地网站建设
  • 如何增加网站权重企业网站分析报告
  • 网站设计框架郑州哪些公司做网站建设