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

相关文章

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

Nginx部署React项目时重定向循环问题的解决方案

《Nginx部署React项目时重定向循环问题的解决方案》Nginx在处理React项目请求时出现重定向循环,通常是由于`try_files`配置错误或`root`路径配置不当导致的,本文给大家详细介... 目录问题原因1. try_files 配置错误2. root 路径错误解决方法1. 检查 try_f

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La