Flutter循环滑动的PageView

  • 序言
  • 准备新的数据源
  • 定时切换
  • 滑动冲突

序言

Android原生里一般会使用ViewPager来实现Banner区域,当然Flutter中的PageView也可以实现类似的效果,今天就来撸一把循环滑动的PageView。

在Android中想要实现循环滑动的ViewPager,最常用的方法是,在原数据源的基础上,通过前后补位来操作:即准备新的数据集合list , 第一个位置插入原数据中的最后一个元素、最后一个位置插入原数据中的第一个元素,Flutter中PageView实现循环滑动的方法如出一辙,如下图所示:


在用户滑动过程中,当(2)被选中后,无动画切换到2的位置;当(0)被选中后,此时无动画切换到0的位置。即可实现循环滑动的PageView。

准备新的数据源

这里需要解释下,如果只有一个数据的话,不考虑循环滑动

  /// 初始化Page/// 准备一个新的数据源list/// 在原数据data的基础上,前后各添加一个view  data[data.length-1]、data[0]void _initWidget() {currentIndex = widget.controller.initialPage;if (widget.children == null || widget.children.isEmpty) return;if (widget.children.length == 1) {_children.addAll(widget.children);} else {_children.add(widget.children[widget.children.length - 1]);_children.addAll(widget.children);_children.add(widget.children[0]);}}

当用户在滑动到新位置的Page后,会触发PageView的回调监听onPageChanged(int index),参数即为新选中的Page索引,此时我们需要及时将页面切换到正确的位置

/// Page切换后的回调,及时修复索引void _onPageChanged(int index) async {if (index == 0) {//当前选中的是第一个位置,自动选中倒数第二个位置currentIndex = _children.length - 2;await Future.delayed(widget.duration);widget.controller?.get()?.jumpToPage(currentIndex);realPosition = currentIndex - 1;} else if (index == _children.length - 1) {//当前选中的是倒数第一个位置,自动选中第二个索引currentIndex = 1;await Future.delayed(widget.duration);widget.controller?.get()?.jumpToPage(currentIndex);realPosition = 0;} else {currentIndex = index;realPosition = index - 1;if (realPosition < 0) realPosition = 0;}setState(() {});}

定时切换

目前已经实现了PageView的循环滑动,那么现在我们加一个定时器,每隔2s自动切换下一个页面。

/// 创建定时器void createTimer() {if (widget.isTimer) {cancelTimer();_timer = Timer.periodic(widget.delay, (timer) => _scrollPage());}}/// 定时切换PageView的页面void _scrollPage() {++currentIndex;var next = currentIndex % _children?.length;widget.controller?.get()?.animateToPage(next,duration: widget.duration,curve: Curves.ease,);}/// 开始定时滑动void _start() {if (!widget.isTimer) return;if (!isActive) return;if (_children.length <= 1) return;createTimer();}/// 停止定时滑动void _stop() {if (!widget.isTimer) return;cancelTimer();}/// 取消定时器void cancelTimer() {_timer?.cancel();}

滑动冲突

到这里就实现了可以定时自动循环滑动的PageView,但是看下实际效果你会发现,当用户在滑动过程中,定时器还在进行,此时就需要取消定时器,当用户手指离开后再开启定时器自动轮播。

所以这里你可以给PageView包裹一层NotificationListener来监听用户滑动

@overrideWidget build(BuildContext context) => NotificationListener(onNotification: (notification) => _onNotification(notification),child: PageView(scrollDirection: widget.scrollDirection,reverse: widget.reverse,controller: widget.controller?.get(),physics: widget.physics,pageSnapping: widget.pageSnapping,onPageChanged: _onPageChanged,children: _children,dragStartBehavior: widget.dragStartBehavior,allowImplicitScrolling: widget.allowImplicitScrolling,restorationId: widget.restorationId,clipBehavior: widget.clipBehavior,),);
/// Page滑动监听_onNotification(notification) {if (notification is ScrollStartNotification) {isEnd = false;} else if (notification is UserScrollNotification) {//用户滑动时回调顺序:start - user , end - userif (isEnd) {isUserGesture = false;_start();return;}isUserGesture = true;_stop();} else if (notification is ScrollEndNotification) {isEnd = true;if (isUserGesture) {_start();}}}

值得注意的是,自动滑动和用户滑动都会触发start、end事件,但是用户滑动时会触发user事件,滑动时回调顺序:start - user 、 end - user,所以只需要在user事件回调中判断是否手指离开了,即可区分用户滑动和页面滑动,实现用户滑动状态下暂停定时器,用户手指离开后启动定时器。

看下最终的实现效果,代码里时加了页面圆点指示器的,可以参考代码自定义配置。

插件地址:

Github
pub.dev

Flutter无限循环滑动的PageView相关推荐

  1. ViewPager系列之ViewPager无限循环滑动

    目前ViewPager实现无限循环有2种方法,直接上具体方法: 方法1:重写 PagerAdapter 中的 getCount() 方法.其实只是在计算item 数目的时候给了一个很大的数,然后通过调 ...

  2. Android使用ViewPager实现左右循环滑动及轮播效果

    ViewPager是一个常用的android组件,不过通常我们使用ViewPager的时候不能实现左右无限循环滑动,在滑到边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的Vie ...

  3. 使用recyclerView实现无限循环banner效果

    新接到的任务就是要搞个能快速滑动好几页的banner控件,之前用的是viewpager实现,尝试过基于viewpager改感觉不太好实现,后面在群友推荐下改用了recycleview,大概都实现了. ...

  4. ViewPager循环滑动和靠按钮来控制循环滑动

    ViewPager用按钮来控制,昨天说了一种方式是直接设置setcurrentItem(),但是今天发现如果我们要设置viewpager循环滑动的话这种方式似乎不可行,于是看源码发现了Viewpage ...

  5. 第一个Flutter demo——实现无限循环列表

    第一个Flutter demo(一) 参照flutter官网,实现第一个Flutter应用.第一部分:实现无限循环列表 第一部分功能介绍: 从零开始创建了一个 Flutter 应用: 编写 Dart ...

  6. 微信小程序 视频列表滑动无限循环(仿抖音)

    一.写在前面: 1:安卓ios表现基本一致,不是swiper组件实现,滑动效果流畅不卡顿,实现了列表无限循环.不是使用官方的腾讯视频播放组件,完整代码在下面 2:实现功能:支持位置导航.拨打电话.复制 ...

  7. 【Android】ViewPager实现无限循环滚动

    最近做的一个项目,客户要求在ViewPager实现的主页面中滑动到最后一页后继续滑动能返回到第一页,也就是实现无限循环滚动,效果如下: 看了下ViewPager没有滑到尽头的回调方法,因此想到的解决方 ...

  8. 安卓开发笔记——自定义广告轮播Banner(实现无限循环)

    关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...

  9. 13岁女孩因发布JavaScript无限循环代码被捕

    据外媒报道,日本刈谷市警方最近逮捕了一名13岁的女学生,指控她在网上公告栏上在线分发恶意代码.这个所谓的恶意代码其实是一个恶作剧,它触发了JavaScript无限循环,在用户访问某个链接时显示&quo ...

最新文章

  1. 编程中的蛇形填空问题_在线编程问题当中的蛇形矩阵问题
  2. ROS学习总结一ROS组织框架与几个关键词
  3. 机器学习与数据科学决策树指南
  4. (素材源码) 猫猫学IOS(十二)UI之UITableView学习(上)LOL英雄联盟练习
  5. 用户体验设计和精益设计的平衡之道
  6. JDBC 8.0 和 JDBC 5.0 区别
  7. paip.项目开发效率提升之思索
  8. 大数据-玩转数据-Oracle系统知识小结
  9. 基于SSM开发的海量值班管理系统 JAVA
  10. 用Excel和OutLook实现自动批量发邮件
  11. 10分钟学会发送邮件到指定邮箱
  12. 人机智能交互技术(ROS)实践作业模版与说明
  13. 从高德地图获取城市公交线路+站点
  14. python中gensim库详解
  15. 0914WEB漏洞-二次,加解密,DNS等注入
  16. FreeRTOS中的堆栈计算
  17. 分类模型评价指标说明
  18. 7-3 判断闰年及星期几 (20 分)
  19. 华为,小米开关控制设置指南总自动弹出
  20. 爱了,爱了,一款拯救直男的开源神器!

热门文章

  1. HDU 6411 带劲的and和【枚举贡献】
  2. Android开发者接口mock location demo
  3. 芒果不能用百度了,怎么办?
  4. 不可思议:99%的人不了解的真实中国历史
  5. Java bean中字段命名潜规则,前两个字母要么都大写,要么都小写
  6. Linux中升级GLIBC,终结版,测试通过
  7. Android借助bmob实现简单的登陆注册
  8. (有趣)把文字隐藏到图片中
  9. 从0开始搭建Hadoop2.x高可用集群(HDFS篇)
  10. barcode--php生成条形码