Flutter——PageView的PageController源码分析笔记

49 篇文章 6 订阅
订阅专栏
49 篇文章 0 订阅
订阅专栏
47 篇文章 0 订阅
订阅专栏

前言

由于公司需求,对PageView的PageController的进行了拆解,这里将所记得笔记分享一哈。

PageController

构造函数 简介

PageController继承自ScrollController extends ChangeNotifier(pageController并没有做什么扩展、只是复写了一些方法),由ChangeNotifier可见controller中的属性是可以向外通知的。(具体可见Provider)
构造函数:

  PageController({
    this.initialPage = 0,   //初始显示的页面
    this.keepPage = true,   //是否保持页面
    this.viewportFraction = 1.0, //viewport 系数
  })

viewportFraction是一个系数,决定pageview的page的大小,即(假设是横向):外层容器宽度*viewportFraction。
同时在滚动的位置计算也会用到这个变量,具体后面会见到

PageController 内部结构图

createScrollPosition()

其中这个方法会在父类的_updatePosition()中调用,而 _updatePosition()在这里两个生命周期中会调用:

didChangeDependencies(),didUpdateWidget(),

由此可见,createScrollPosition()在页面创建和刷新时是会调用。
它会返回一个 _PagePosition():

return _PagePosition(
      physics: physics,
      context: context,
      initialPage: initialPage,
      keepPage: keepPage,
      viewportFraction: viewportFraction,
      oldPosition: oldPosition,
    )

其中physics,我们没传的话,系统会默认传一个_kPagePhysics(类PageScrollPhysics),另外在使用pageview时,如果我们不传controller,系统也会传一个默认的 _defaultPageController(类PageController)。

接下来我们看一下PageScrollPhysics,(之后再回来看_PagePosition)

PageScrollPhysics 及结构图

PageScrollPhysics 继承自ScrollPhysics,用来决定滚动时的物理特性。如果你对pageview、listview等等的滚动效果不满意,就可以从这里入手,定义自己的physics。

它主要有4个方法,分别是:

_getPage(ScrollMetrics position)

_getPixels(ScrollMetrics position, double page)

_getTargetPixels(ScrollMetrics position, Tolerance tolerance, double velocity)

以上三个是用于根据页面取得滚动位置或者根据位置取得页面的,他们三个组合到一起,就可以实现pageview 的一次滚动一个页面、滑动过半自动滚动到下一页的效果。

第4个方法createBallisticSimulation(ScrollMetrics position, double velocity)

该方法会组装一个含有起点和终点的,滑动时带有弹簧阻尼效果的Simulation,并返回。
具体哪里用到,后面会说,这里我们回到_PagePosition

_PagePosition

这里结构比较复杂,较深的类我只贴结构图(内带注释),尽量减少文字。
继承关系(上到下:子到父):
_PagePosition
    ↓
ScrollPositionWithSingleContext implements ScrollActivityDelegate
    ↓
ScrollPosition with ScrollMetrics
    ↓
ViewportOffset
    ↓
ChangeNotifier (可以发现、它的子类是具有向外通知的功能的)

ViewportOffset

ScrollPosition

ScrollMetrics

ScrollPositionWithSingleContext

这个类是pagePosition的直接父类,它实现了接口ScrollActivityDelegate(抽象类。dart实际没有接口的概念),ScrollActivityDelegate定义了几个方法其中常用的是:

void goIdle();  //停止滚动

void goBallistic(double velocity);//弹性滚动

我们就来看一看goBallistic的具体实现吧:

  @override
  void goBallistic(double velocity) {
    assert(pixels != null);
    final Simulation simulation = physics.createBallisticSimulation(this, velocity);
    if (simulation != null) {
      beginActivity(BallisticScrollActivity(this, simulation, context.vsync));
    } else {
      goIdle();
    }
  }

注意这句:physics.createBallisticSimulation(this, velocity); 这里就是调用我们上面说的PageScrollPhysics中的方法createBallisticSimulation,它返回的simulation用于生成一个BallisticScrollActivity会交给beginActivity来处理(没有返回的话就呆住啦~)。

我们先来了解一下ScrollActivity

ScrollActivity

ScrollActivity是个抽象类、内部有一些分发通知的方法和几个变量,如:是否滚动、滚动速度等等。
flutter里,据我所知各种的滚动样式活动(drag、fling等)都是继承自ScrollActivity。如上面的BallisticScrollActivity。对于它的理解我是这样想的:
Simulation是描述一个物理效果、ScrollActivity的子类来展现这个效果,我们看一下他的构造函数就一目了然了:

  BallisticScrollActivity(
    ScrollActivityDelegate delegate,
    Simulation simulation,
    TickerProvider vsync,
  ) : super(delegate) {
    _controller = AnimationController.unbounded(
      debugLabel: kDebugMode ? objectRuntimeType(this, 'BallisticScrollActivity') : null,
      vsync: vsync,
    )
      ..addListener(_tick)
      ..animateWith(simulation)
       .whenComplete(_end); // won't trigger if we dispose _controller first
  }

回到ScrollPositionWithSingleContext

虽然pagePosition 继承自ScrollPositionWithSingleContext,但是pagePosition里的方法并不多、主要是加了这两个方法:

getPageFromPixels(),getPixelsFromPage()

这些方法在PageScrollPhysics中会用到(辅助达到一次一页的效果)。

父类ScrollPositionWithSingleContext内部定义了我们常见animateTo(),jumpTo()等等、对应的会生成一些列scrollActivity的子类用于驱动,如:DrivenScrollActivity\BallisticScrollActivity\IdleScrollActivity

这里再放一下controller的结构图(注意左侧):

到这里pagePosition的内部结构就基本解剖完了,同时也回到了最初的controller的createScrollPosition,即整个控制流程的分析就结束了。

文章比较长,谢谢大家观看。若有错误的地方或者没说明白的,还请指正,感谢。

意外发现

扒源码的时候,我发现官方的scrollcontroller 实际上是支持指定item进行滚动的,我们可以看一下上面scrollPosition的结构图(图内底部),其中有一个方法ensureVisible(),可以滚动到指定的RenderObject,目前我试了一下scrollView等(非回收的)效果完美。但是listview不行(屏幕内可以),应该是由于listview的屏外child(超出缓存)会被回收的原因的,拿不到RenderObject,这个还是有待研究。 大家有啥想法可以交流一哈。

相关文章

PageView源码和Gesture竞技场消歧的浅析

其他文章:

Bedrock——基于MVVM+Provider的Flutter快速开发框架

[特斯拉组件]ios高性能PageController
腾讯Bugly的专栏
09-19 1950
UIPageViewController的DataSource和Delegate的接口过于简单,对于比较复杂的情况(比如除了分页以外还有其他View的情况下)无法处理。参照下面的例图,我有一个tab下面有小黄条,跟着手势横向滑动的同时也横向滑动,这里系统的UIPageViewController无法支持。其外,我还需要子页面纵向滑动时候去修改Cover和Tab的frame。所以UIPageViewControlle
pageViewController实现多视图(控制器)滑动切换
flg1554112450的博客
07-12 7656
先看一下效果动画 类似的界面做过不少,,在几个APP中都有用到过,,再次之前不了解uipageViewController 曾经的思路有两个现在想想都觉得繁琐,, 之前的思路1:使用嵌套,collectionview嵌套,每个item中添加内容 之前的思路2:使用scrollview 在上面创建一个一个的controller 实现左右滑动 这两个思路无疑是可以实现的 并且可
Flutter——Android Studio下环境配置
01-03
引言 前段时间,制定了今年的学习计划,包括前端优化(打包、测试、发布)、数据可视化、Vue3.0源码阅读、Flutter、算法和数据结构。 所以,最近也陆续开始今年的学习计划,先拿 Flutter开刀(hhh),当然第一步就是开发环境的配置。那么,我们就来讲讲如何配置 Android Studio+ Flutter的开发环境。 一、安装 Flutter SDK 首先,新增两个系统变量,主要用于后期 Flutter检测时的安装,此电脑->属性->高级->环境变量。 export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_ST
flutter PageView实现左右滑动切换视图
08-25
主要为大家详细介绍了flutter PageView实现左右滑动切换视图,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
flutter线上项目源码
09-28
一个小型flutter项目源码
Flutter PageView属性说明
杰森丶郭达斯坦森的博客
01-02 643
AlwaysScrollableScrollPhysics:这种物理特性会始终响应用户的滑动手势,即使内容已经不可滚动。FixedExtentScrollPhysics:这种物理特性用于每次滚动一个固定大小的项目(例如,在水平方向上滚动单个列),并且不允许在项目之间停止。NeverScrollableScrollPhysics:这种物理特性会禁止用户通过手势滚动页面,通常用于静态页面或者需要根据代码来控制滚动的情况。这些物理特性可以根据你的页面视图需求来选择。PageController的属性说明。
设计randompool结构
Mr_zhang66的博客
11-05 202
哈希表是get每一个key的value,而本题没有value,只有key 我们准备两张哈希表,以及一个变量 :size。 一个表存放某 key 的标号,另一个表根据根据标号取某个key 如下图所示: A是第0个进来的 B是第二个进来的 我们现在先忽略remove行为 。 就这样一直加到25 此时size为26 现在用户让我随机等概率返回一个数,怎么做? 因为我有size,我可以用math.random函数随机出0-25中的等概率的一个,随机出来的是哪个数字,在map2里面把哪个数字的字符串返回 一.
一个很酷的PageViewController-Swift开发
05-27
使用CocoaPods安装HJTabViewController CocoaPods是Objective-C的依赖项管理器,它可以自动化并简化在项目中使用第三方库的过程。 请参见《使用CocoaPods进行HJTabViewController安装》。CocoaPods是Objective-C的依赖项管理器,它可以自动化并简化在项目中使用第三方库的过程。 有关更多详细信息,请参见“入门”部分。 Podfile pod'HJTabViewController','〜> 1.0'或pod'HJTabViewController',:git =>'https://github.com/panghaijiao/HJTabViewController.git',:tag =>'1.0.5'已发布许可证HJTabViewController根据MIT许可。 请参阅d的许可
Flutter 实现 PageView 指示器
buniejin9470的博客
07-15 572
本篇用一个PageView的实例来加深印象,并且在之后的专栏里,我们会深化这个示例,做成一个支持上下左右无限滑动的图片Banner,并且教你如何把他做成Dart library并且开放给其他人使用。 一.无限滑动的PageView 在实现PageView指示器之前,咱们需要先实现一个PageView。在Flutter中实现一个PageView很简单。 class BannerGalleryWidg...
Web Page Controller(页面控制器)
Frank的专栏
04-29 2819
Page Controller(页面控制器)发布日期: 4/1/2004 | 更新日期: 4/1/2004Page Controller(页面控制器)版本: 1.0.1本页内容上下文问题影响因素解决方案示例结果上下文测试考虑事项相关模式致谢上下文您已经决定使用 Model-View-Controller (MVC) 模式来将动态 Web 应用程序的用户界面组件与业务逻辑分隔开来。要构建的应用程序将
iOS使用pageViewController实现多视图滑动切换
08-27
主要为大家详细介绍了iOS使用pageViewController实现多视图滑动切换,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
SCPageViewController, 就像UIPageViewController但是更好.zip
09-18
SCPageViewController, 就像UIPageViewController但是更好 SCPageViewControllerSCPageViewController是一个类似UIPageViewController的容器视图控制器,但它提供了更多的控制,更可以定制。 它支持以下功能:可以定制的过渡和动画( 通过la
Flutter pageview切换指示器的实现代码
08-26
主要介绍了Flutter pageview切换指示器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Flutter —— 自定义 Widget
01-07
import 'package:flutter/material.dart' class Example extends StatelessWidget { @override Widget build(BuildContext context) { return Text(无状态小部件) } } 2. 有状态 StatefulWidg
Flutter】使用PageStorage在页面切换时保存状态
移动端开发干货分享
04-04 3682
Tab切换时的问题 在一个SPA的Flutter项目中可以用StatefulWidget保存页面状态,但是当出现页面切换的情况时,例如通过底部导航栏(BottomNavigationBar)或者标签栏(TabBar)组件来切换页面内容,每次导航栏或标签栏切换页面时,之前的页面就被清理了。 出现上面问题的原因是,之前页面的状态(State)没有被保留下来,状态的reset导致页面发生了初始化。 ...
Flutter 中的 PageView 控件:全面指南
最新发布
smileKH的博客
05-12 489
PageView允许你自定义页面切换效果,通过Theme(},),),// ... 其他属性),PageViewFlutter 中一个强大且灵活的控件,它不仅支持水平和垂直滚动,还可以通过和监听器进行详细的页面控制。掌握PageView的使用,可以帮助你在 Flutter 应用中创建出吸引人的分页视图和流畅的用户体验。
Flutter实现iOS TabBarController效果和android TabHost效果
我叫柱子哥
06-22 665
先上截图, 如何实现下图的效果呢。对于iOS开发者,我们可以使用UITabBarController来实现,对于android开发者,我们可以使用FragmentTabHost来实现。在Flutter中并没有这两个控件,进入正题,我们看看在Flutter中我们如何使用Flutter中的PageView来实现这种效果。
FlutterPageView的滑动开始监听、完成监听自定义
吃松子的猫的博客
11-23 5608
最近Flutter项目开发中,用到了PageView的上下滚动,但是正常的PageView的使用,onPageChanged的回调,在页面滑到中间的时候,就会把下一个页面的pageIndex值传递过来。但是实际需求中,我需要知道什么时候页面滑动结束,这时候才去执行页面完全展示的方法。所以就需要对PageView进行自定义改造。 一、尝试了使用系统自带的PageController进行滑动监听,失败 开始尝试使用系统给的api进行监听 结果发现,返回的...
Flutter--PageView学习
油焖茄子 的博客
11-09 1250
PageView:滑动视图列表,类型AndroidViewPage控件,不过PageView支持上下滑动,可制作轮播图。
flutter TabBar pageview组合使用
05-19
Flutter中,可以通过将TabBar和PageView组合在一起来创建具有选项卡的页面滚动视图。下面是一个简单的示例,演示如何使用TabBar和PageView来创建具有选项卡的页面滚动视图。 首先,我们需要在代码中导入必要的库: ```dart import 'package:flutter/material.dart'; ``` 然后,我们可以创建一个StatefulWidget,其中包含一个TabBar和一个PageView。在这个示例中,我们将创建一个具有三个选项卡的滚动视图,每个选项卡都包含一个文本控件。 ```dart class MyTabbedPage extends StatefulWidget { @override _MyTabbedPageState createState() => _MyTabbedPageState(); } class _MyTabbedPageState extends State<MyTabbedPage> { final List<Tab> myTabs = <Tab>[ Tab(text: 'Tab 1'), Tab(text: 'Tab 2'), Tab(text: 'Tab 3'), ]; @override Widget build(BuildContext context) { return DefaultTabController( length: myTabs.length, child: Scaffold( appBar: AppBar( title: Text('My Tabbed Page'), bottom: TabBar( tabs: myTabs, ), ), body: TabBarView( children: myTabs.map((Tab tab) { return Center(child: Text(tab.text)); }).toList(), ), ), ); } } ``` 在这个示例中,我们首先定义了一个包含三个选项卡的TabBar。然后,我们使用DefaultTabController来指定选项卡的数量,并将TabBar包装在AppBar中。最后,我们使用TabBarView来构建页面视图,并将一个文本控件放在每个选项卡中间。 现在,我们可以将MyTabbedPage添加到我们的应用程序中: ```dart void main() { runApp(MaterialApp( title: 'My App', home: MyTabbedPage(), )); } ``` 这样,我们就可以创建一个具有选项卡的页面滚动视图,用户可以在不同的选项卡之间滚动并查看不同的页面内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

分类专栏

  • android 49篇
  • flutter 49篇
  • 前端 47篇
  • 快速开发框架 2篇
  • MVVM 1篇

最新评论

  • Android WebView拉起软键盘的流程浅析

    城_: 我虽然云里雾里,但是觉得还是不错的文章,为啥没人看

  • Flutter 之简洁实用的图片编辑器

    weixin_37659655: 怎么修改呢,我改了咋还是不行

  • Flutter 之简洁实用的图片编辑器

    tabbycute: 我也遇到了,.symlinks下面找到插件,改一下就好了

  • Flutter 之简洁实用的图片编辑器

    yixiu03: ios一直报[!] No podspec found for `image_editor_dove` in `.symlinks/plugins/image_editor_dove/iOS`,大家有遇到这个情况吗

  • Flutter 之简洁实用的图片编辑器

    minqingnu: 是通过截屏合成,不是实际操作图片处理的,合成的图像会模糊

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • (翻译) 识别&处理Android构建时的内存问题
  • 坦克对战 : Flutter&Flame在游戏上的实践
  • 关于MockView中“Mock“编程思想的个人理解及实践
2022年5篇
2021年9篇
2020年35篇
2019年1篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司普洱网站优化按天计费价格宿迁外贸网站制作报价阜新seo优化多少钱毕节网站优化按天扣费多少钱运城网站推广系统价格茂名百搜标王报价潍坊网站关键词优化报价临夏网站推广推荐昌都网站制作公司金昌百姓网标王价格伊春seo排名哪家好吉安网站优化排名价格抚州网站优化排名哪家好桂林网站制作设计多少钱十堰关键词排名推荐咸阳百度关键词包年推广推荐福永百度网站优化排名清徐营销网站价格黑河高端网站设计哪家好福永企业网站改版常州网络营销公司延安网络营销多少钱天津模板制作吴忠英文网站建设报价惠州企业网站制作推荐延安网站关键词优化多少钱怀化百姓网标王推广价格大丰SEO按天计费多少钱四平网站设计模板榆林高端网站设计哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化