热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flutter列表抖动,flutter滑动掉帧

关于flutterNestedScrollView导致其body的tabbarview的多个list同步滚动的解决方案讲道理我起的好长的名字啊,不过文如上题,搜索到这里的兄弟应该都

关于flutter NestedScrollView导致其body的tabbarview的多个list同步滚动的解决方案

讲道理我起的好长的名字啊,不过文如上题,搜索到这里的兄弟应该都知道我说的是啥情况,正好

~~

我这个方案可能有点笨拙TT,不过自测有效,有其它想法的老哥希望可以帮忙指点一下~

下面进入正题

点进源码里面看,可以发现他直接继承了StatelessWidget,那我们就直接看看build方法

可以看到,这里直接返回一个scrollable或者一个子节点是scrollable的InheritedWidget

scrollable是一个StatefulWidget,那我们就看看它的state

首先scrollable持有一个scrollposition对象,是通过其scrollcontroller构建的

在其state的setCanDrag方法中,对其拖动设置了一系列的监听

这里就可以看出来,当拖动触发时,就会通过当前scrollable的position生成一个Drag/Hold对象,并调用相应的方法 这个position有几个子类,我们先随便看一个实现

可以看到生成了一个ScrollDragController对象,当手势拖动而调用这个对象的update方法时

可以看到直接调用其委托对象的applyUserOffset方法进行偏移,而这个委托对象根据刚才的drag方法可以得知正是我们scrollable中的position

最后,由position通知其scrollcontext,也就是之前的scrollable进行滑动

具体的滑动流程这里就不细说了,我们只是要知道这个事件是怎么传递的就好了,有兴趣的老哥可以自行分析

NestedScrollView是一个statefulwidget,那我们就先看看它的build方法

先忽略其他奇奇怪怪的方法,我们发现在我们body的外面,包裹了一层PrimaryScrollController,同时它还持有innerController,这个innerController暂时先不管它是啥

还记不记得在最开始ScrollView的build方法中,生成Scrollable的时候,我们已经见过这个PrimaryScrollController了,再回顾一下

再看看PrimaryScrollController.of(context)

可以看到,在生成scrollable的时候,在primary = true的情况下是会向上查找的,看看有没有PrimaryScrollController,如果有的话,scrollable使用的controller实际就是nestedscrollview中的innerController了

而之前看过了,scrollable中的position就是scrollcontroller来生成的,那么在这种情况下:

实际上是生成了_NestedScrollPosition并返回给了body中的scrollable

构造方法中有一个参数coordinator 暂时先不管

好了,下面我们在回头看刚才NestedScrollView的build方法,实际上是生成了一个_NestedScrollViewCustomScrollView,继承自大名鼎鼎的CustomScrollView,它当然也是scrollview啦,而我们传给它的controller也是一个_NestedScrollController,不过叫做_outerController,和body中的不是同一个罢了,那么自然这个父scrollview的position也是_NestedScrollPosition。

下面我们按照之前的逻辑,当拖动开始时,就会调用position.drag方法

可以看到,实际上吧方法交给了我们之前多次见到的coordinator来完成,那我们就简单看一下吧

这里可以看到,他把返回的ScrollDragController的委托者设成了自己

那么自然在拖动的时候,调用的就是coordinator的applyUseroffset方法了 我们分析一下

可以看到,在需要子列表滚动时,是对innerPositions中的所有position调用滑动方法的

而这innerPositions中的position是怎么来的呢?跟踪一下可以发现是在调用NestedScrollController的attach时添加进来的,如下

因为之前我们看到过,子scrollable中的controller就是这个NestedScrollController,所以在updateopsition时会把旧的detach调,把新生成的position attach进来

另外,在dispose中也会detach

由此我们就知道啦,因为开启了缓存后就不会调用划出屏幕的页面的dispose,自然所有子scrollable的position都存在nestedScrollController里面了,当发生滑动时,遍历调用positions数组,就导致屏幕外的列表也跟着滑动了~

既然开启了缓存,手动dispose肯定是没啥意义的,实际上我们只要在页面切换过后把未显示的position 给detach掉就好了。

然鹅,因为flutter不支持反射,子布局传递的position我们拿不到,nestedScrollController我们也不能直接拿到=。=

不过有一个对象我们之前见到过,scrollable就是通过他获取controller的,而position则是传给了获取到的controller 就是PrimaryScrollController了,所以我打算在中间第三者插足,对传递Position的PrimaryScrollController进行Hook

在使用的时候把子列表添加进去,并设置对应的GlobalKey。

然后监听Tab切换

以上是我的方案,有问题的话还希望老哥帮忙指正,也希望有其他思路的老哥指点一下~~

上一下Github项目地址 用Flutter写的WanAndroid 其中用到了这个方案

= =

3

Flutter:手把手教你使用滚动型列表组件:ListView

ListView的基础创建使用有三种方式:

通过默认构造函数来创建列表,应用场景 = 短列表

这种方式创建的列表存在一个问题:对于那些长列表或者需要较昂贵渲染开销的子组件,即使还没有出现在屏幕中但仍然会被ListView所创建,这将是一项较大的开销,使用不当可能引起性能问题甚至卡顿。

长列表

列表子项之间需要分割线

ListView的进阶使用主要包括:下拉刷新 上拉加载

在Flutter中,ListView结合RefreshIndicator组件实现下拉刷新

通过包裹一层RefreshIndicator,自定义onRefresh回调方法实现

方式有两种:

通过ListView.controller属性可以判断ListView是否滑动到了底部,再进行上拉加载

NotificationListener是一个Widget,可监听子Widget发出的Notification

ListView在滑动时中会发出ScrollNotification类型的通知,可通过监听该通知得到ListView的滑动状态,判断是否滑动到了底部,从而进行上拉加载

NotificationListener有一个onNotification属性,定义了监听的回调方法,通过它来处理加载更多逻辑

不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度 。

Flutter 之列表和头部 (ListView + Header)

上一篇介绍Banner的开发。在大多数应用场景中。banner和ListView通常是一起显示的。 并且能够共同滑动。例如如下界面:

要实现上图的界面,直接想到是ListView添加Header。但在Flutter中,ListView 组件相当于RecyclerView,所以添加Header也用RecyclerView的原理:

封装ListPage组件,list_page.dart

使用及测试:异步加载网络数据使用

什么叫抖晃率

Flutter(抖动)、Wow(晃动)、Drift(漂移)、Scrape Flutter(刮颤)是以移动介质为记录材料做模拟录制和回放的系统所需要面对的几种失真。这些失真是在录制、复制、回放过程中,由于记录介质的不规则的运动而导致的令人不快的频率调制所引入信号中的。抖晃率用于定量描述这种由于介质的运动速度不稳定所造成的频率晃动对人耳的主观影响。比如回放一个精准3150Hz的正弦信号,在理想的无抖晃的情况下,播放出来的信号就是3150Hz,然而在实际有抖晃的情况下,播放出来的信号的瞬时频率将围绕某个均值(不一定正好等于3150Hz)不断变动,就是说相对于那个均值有往复变化的频偏。

Drift(漂移)指的是信号中的频偏低于大约0.5Hz的频率调制。它给人的感觉是平均音调的缓慢变化。

Wow(晃动)指的是信号中的频偏范围为大约0.5Hz~6Hz的频率调制。它给人的感觉是音调的波动。

Flutter(抖动)指的是信号中的频偏范围为大约6Hz~100Hz的频率调制。它给人的感觉是声音品质的粗糙化。

Scrape Flutter(刮颤)指的是信号中的频偏高于大约100Hz的频率调制。它由磁带的粘连-滑动(粘滞)运动造成。它给人的感觉是声音中有噪音,而这种噪音在没有信号时是不存在的。这种噪音也称为摩擦噪音或粘滞噪音。

目前有多种抖晃率测试标准,例如:CCIR,DIN, NAB, JIS等,这里介绍的是基于AES(Audio Engineering Society)的AES6-2008(r2012)标准(就是2012年的最新修订版),它与IEC 60386、IEEE Std-193、CCIR 409-2和DIN 45507标准兼容。标准测试信号的频率定为3150Hz。当然用3000Hz的测试频率或其他的频率,这里介绍的方法也适用。

《摘自Multi-Instrument软件说明书》

Flutter性能优化

1.圆角对性能的影响

尽量避免用Clipxxx组件,建议用BoxDecoration的image属性实现,如果用Clipxxx组件,圆角取整后性能会提升。

2.减少重绘

根据场景合理使用RePaintBoundary,使绘制独立于父布局,避免重绘,提升性能,但过度使用增加的图层会带来Raster合成的耗时。例如scrollview是滑动过程会导致所有的节点都重绘,可以在scrollview下一层使用RePaintBoundary。

3.滚动步长插值器优化(了解)

官方的滚动差值器在出现小卡顿时,滚动步长会出现大的跳跃,导致体感上出现很明显的抖动,优化步长偏移量算法与原生效果对齐。

4.开启SurfaceView

官方推荐Flutter用SurfaceView ,因为SurfaceView与应用窗口内容分隔开,在专有硬件中合成,产生的中间副本少于TextureView,所以性能高,占用内存少,但是在混合栈遇到的问题需要突破

5.使用RepaintBoundary 提升频繁重绘控件的性能。使用RelayoutBoundary提升频繁修改大小,增删的布局中也可以提升性能。

6.build中不要去写大量的耗时逻辑,因为数据更新会触发build的多次调用,在里面做耗时逻辑会降低性能。

7.尽量使用statelessWidget代替statefulWidget,因为statefulWidget的销毁重建会引起子widget的销毁与重建。

8.解析json可以放到子线程线程中,开Isolate去解析,这样,当返回数据特别大的时候也不会阻塞界面。

9.使用不变的组件的时候可以添加const,const组件不会进行build更新

10.由于flutter通过widget.runtimeType和key来判断是否需要跟新组建,所以我们写组件的时候尽量保持key不变,或者不写key。对于一些需要频繁改变,例如新增、删除、排序的最好加上key。如果type一直,如果不写key容易导致,element无法区分新旧widget,导致无法更新。


推荐阅读
  • 使用Flutternewintegration_test进行示例集成测试?回答首先在dev下的p ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • [翻译]PyCairo指南裁剪和masking
    裁剪和masking在PyCairo指南的这个部分,我么将讨论裁剪和masking操作。裁剪裁剪就是将图形的绘制限定在一定的区域内。这样做有一些效率的因素࿰ ... [详细]
  • fileuploadJS@sectionscripts{<scriptsrc~Contentjsfileuploadvendorjquery.ui.widget.js ... [详细]
  • 注:根据Qt小神童的视频教程改编概论:利用最新的Qt5.1.1在windows下开发的一个小的时钟程序,有指针与表盘。1.Qtforwindows开发环境最新的Qt已经集 ... [详细]
  • 当我在doWork方法中运行代码时,通过单击button1,进度条按预期工作.但是,当我从其他方法(即btn2,btn3)将列表传递给doWork方法时,进度条在启动后会跳转到10 ... [详细]
  • java unhandled,Eclipse编辑java文件报Unhandled event loop exception错误的解
    本人Eclipse版本是”eclipse-jee-kepler-SR2-win32-x86_64“昨天因为换电脑,所以重装了一下软件,装好eclipse ... [详细]
  • 先上图引入插件在pubspec.yaml中引入charts_flutter插件使用的时候版本到0.6.0,插件地址:https:github.comgooglecharts使用插件 ... [详细]
  • C# 三个Timer
    在C#中存在3种常用的这个 ... [详细]
author-avatar
一诺千金2502859287
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有