Flutter无限循环滑动的PageView

2024-03-04 01:18

本文主要是介绍Flutter无限循环滑动的PageView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/771553

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

Flutter Button使用

Material 组件库中有多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们的父类是于ButtonStyleButton。         基本的按钮特点:         1.按下时都会有“水波文动画”。         2.onPressed属性设置点击回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

校验码:奇偶校验,CRC循环冗余校验,海明校验码

文章目录 奇偶校验码CRC循环冗余校验码海明校验码 奇偶校验码 码距:任何一种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据检验码的码距。 奇偶校验码的编码方法是:由若干位有效信息(如一个字节),再加上一个二进制位(校验位)组成校验码。 奇校验:整个校验码中1的个数为奇数 偶校验:整个校验码中1的个数为偶数 奇偶校验,可检测1位(奇数位)的错误,不可纠错。

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

Spring是如何解决循环依赖?

现象解释: 在Spring框架中,循环依赖(Circular Dependency)是指两个或多个Bean之间相互依赖,形成了一个循环。例如,Bean A依赖于Bean B,而Bean B又依赖于Bean A。Spring通过多种机制解决循环依赖问题,具体来说,主要有以下几种方式: 1.三级缓存机制 Spring容器在实例化Bean时使用了三级缓存来解决循环依赖,主要涉及三个缓存结构: 一级

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

颠覆你的开发模式:敏捷思维带来的无限可能

敏捷软件开发作为现代软件工程的重要方法论,强调快速响应变化和持续交付价值。通过灵活的开发模式和高效的团队协作,敏捷方法在应对动态变化和不确定性方面表现出色。本文将结合学习和分析,探讨系统变化对敏捷开发的影响、业务与技术的对齐以及敏捷方法如何在产品开发过程中处理持续变化和迭代。 系统变化对敏捷软件开发的影响 在敏捷软件开发中,系统变化的管理至关重要。系统变化可以是需求的改变、技术的升级、