Flutter-无限循环滚动标签

1. 序章

在现代移动应用开发中,滑动视图是常见的交互模式之一。特别是当你需要展示大量内容时,使用自动滚动的滑动视图可以显著提升用户体验。在这篇文章中,我们将讨论如何使用 Flutter 实现一个自动滚动的列表视图。

2. 效果

3. 实现思路

为了实现一个自动滚动的列表视图,我们需要考虑以下几点:

  1. ScrollController 管理:每个横向列表需要一个 ScrollController 来管理其滚动状态。
  2. 自动滚动机制:使用 Timer 定时器定期触发滚动事件。
  3. 用户交互管理:通过手势检测来判断用户何时开始或结束手动滚动,并暂停或恢复自动滚动。

4. 实现代码

以下是实现这个功能的完整代码:

import 'dart:async';
import 'package:flutter/material.dart';

//https://github.com/yixiaolunhui/flutter_xy
class LoopScrollWidget extends StatefulWidget {
  final List<List<dynamic>> items;
  final double? rowHeight;
  final Widget Function(BuildContext context, int rowIndex, int index) itemBuilder;

  const LoopScrollWidget({
    Key? key,
    this.rowHeight = 50,
    required this.items,
    required this.itemBuilder,
  }) : super(key: key);

  
  LoopScrollWidgetState createState() => LoopScrollWidgetState();
}

class LoopScrollWidgetState extends State<LoopScrollWidget> {
  late final List<ScrollController> _scrollControllers;
  late final List<bool> _isScrollingList;
  final double _scrollIncrement = 4.0;
  final Duration _scrollDuration = const Duration(milliseconds: 50);
  Timer? _scrollTimer;

  
  void initState() {
    super.initState();
    _scrollControllers = List.generate(widget.items.length, (index) => ScrollController());
    _isScrollingList = List.generate(widget.items.length, (index) => false);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _startAutoScroll();
    });
  }

  
  void dispose() {
    _scrollTimer?.cancel();
    for (var controller in _scrollControllers) {
      controller.dispose();
    }
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: List.generate(widget.items.length, (rowIndex) {
        return GestureDetector(
          onPanDown: (_) => _isScrollingList[rowIndex] = true,
          onPanEnd: (_) => _isScrollingList[rowIndex] = false,
          onTapUp: (_) => _isScrollingList[rowIndex] = false,
          child: NotificationListener<ScrollNotification>(
            onNotification: (notification) {
              if (notification is ScrollEndNotification) {
                _isScrollingList[rowIndex] = false;
              }
              return false;
            },
            child: SizedBox(
              height: widget.rowHeight,
              child: ListView.builder(
                controller: _scrollControllers[rowIndex],
                physics: const BouncingScrollPhysics(),
                scrollDirection: Axis.horizontal,
                itemBuilder: (context, index) {
                  final position = index % widget.items[rowIndex].length;
                  return Row(
                    children: [widget.itemBuilder(context, rowIndex, position)],
                  );
                },
              ),
            ),
          ),
        );
      }),
    );
  }

  void _startAutoScroll() {
    _scrollTimer?.cancel();
    _scrollTimer = Timer.periodic(_scrollDuration, (timer) {
      for (var i = 0; i < _scrollControllers.length; i++) {
        if (!_isScrollingList[i] && _scrollControllers[i].hasClients) {
          _scrollControllers[i].animateTo(
            _scrollControllers[i].offset + _scrollIncrement,
            duration: _scrollDuration,
            curve: Curves.linear,
          );
        }
      }
    });
  }
}

详细解释

  1. Stateful WidgetLoopScrollWidget 继承自 StatefulWidget,其状态管理由 LoopScrollWidgetState 类负责。
  2. 初始化:在 initState 方法中,我们初始化了每个行的 ScrollController 和一个布尔列表 _isScrollingList 来跟踪哪些行正在被手动滚动。
  3. 自动滚动:使用 Timer.periodic 来定时滚动每一行,除非该行当前正在被手动滚动。
  4. 手势检测:使用 GestureDetector 来检测用户何时开始或结束手动滚动,并通过 NotificationListener 来监听滚动结束通知。

详情:github.com/yixiaolunhui/flutter_xy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/725379.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Linux] 历史根源

UNIX系统&#xff1a; 1969年&#xff0c;由贝尔实验室的K.Thompson和D.M.Ritchie为PDP-7机器编写的一个分时操作系统&#xff0c; 最初使用汇编语言编写&#xff0c; 后来1972年C语言出世以后&#xff0c;二人由使用C写了UNIX3&#xff0c; 此后UNIX大为流行开来 UNIX流派树&a…

凌凯科技冲刺上市:2023年业绩反弹,靠关联交易助推业务发展?

近日&#xff0c;上海凌凯科技股份有限公司&#xff08;下称“凌凯科技”&#xff09;向港交所递交上市申请&#xff0c;华泰国际担任其独家保荐人。 透过招股书不难看出&#xff0c;在化学合成一体化这个虹吸效应显著的细分赛道中&#xff0c;凌凯科技拥有头部玩家的先发优势…

数据分析第十三讲:数据可视化入门(二)

数据可视化入门&#xff08;二&#xff09; 本章我们尝试用 matplotlib 来绘制一些高阶统计图表。正如前面所说的&#xff0c;大家可以通过 matplotlib 官方网站上提供的文档和示例来学习如何使用 matplotlib 并绘制出更加高级的统计图表&#xff1b;尤其是在定制一些比较复杂…

人工智能中的监督学习和无监督学习

欢迎来到 Papicatch的博客 目录 &#x1f349;引言 &#x1f349;监督学习 &#x1f348;基本思想 &#x1f348;具体过程 &#x1f34d;数据收集 &#x1f34d;数据预处理 &#x1f34d;模型选择 &#x1f34d;模型训练 &#x1f34d;模型评估 &#x1f34d;模型部署…

【深度学习基础】详解Pytorch搭建CNN卷积神经网络LeNet-5实现手写数字识别

目录 写在开头 一、CNN的原理 1. 概述 2. 卷积层 内参数&#xff08;卷积核本身&#xff09; 外参数&#xff08;填充和步幅&#xff09; 输入与输出的尺寸关系 3. 多通道问题 多通道输入 多通道输出 4. 池化层 平均汇聚 最大值汇聚 二、手写数字识别 1. 任务…

[C++][数据结构][图][下][最短路径]详细讲解

目录 1.最短路径1.单源最短路径 -- Dijkstra算法2.单源最短路径 -- Bellman-Ford算法3.多源最短路径 -- Floyd-Warshall算法原理 1.最短路径 最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&#xff0c;最短也就是沿路径…

spark学习总结

系列文章目录 第1天总结&#xff1a;spark基础学习 1- Spark基本介绍&#xff08;了解&#xff09;2- Spark入门案例&#xff08;掌握&#xff09;3- 常见面试题&#xff08;掌握&#xff09; 文章目录 系列文章目录前言一、Spark基本介绍1、Spark是什么1.1 定义1.2 Spark与M…

valgrind工具的交叉编译及使用

一 概述 valgrind是一款非常好用的工具&#xff0c;用于检测内存泄漏等&#xff0c;这里讲述如何将其交叉编译到arm开发板及如何使用 【C/C 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南 - 知乎 (zhihu.com) valgrind: fai…

60.指针数组和数组指针

一.指针数组 指针数组是一个数组&#xff0c;在指针数组中存放的是指针变量。 定义一个指针数组p int *p[5]; 内存模型如下&#xff1a; 指针数组的初始化 #include <stdio.h>int main(void) {int a1;int b2;int c3;int i;int *p[3] {&a,&b,&c};for(i0…

Unbounded CKKS for Bits NTT with Composite Modulus

参考文献&#xff1a; [CHKKS18] Cheon J H, Han K, Kim A, et al. Bootstrapping for approximate homomorphic encryption[C]//Advances in Cryptology–EUROCRYPT 2018: 37th Annual International Conference on the Theory and Applications of Cryptographic Techniques…

技术差异,应用场景;虚拟机可以当作云服务器吗

虚拟机和云服务器是现在市面上常见的两种计算资源提供方式&#xff0c;很多人把这两者看成可以相互转换或者替代的物品&#xff0c;实则不然&#xff0c;这两种资源提供方式有许多相似之处&#xff0c;但是也有不少区别&#xff0c;一篇文章教你识别两者的技术差异&#xff0c;…

RabbitMQ实践——交换器(Exchange)和绑定(Banding)

大纲 direct型交换器默认交换器命名交换器 fanout型交换器topic型交换器headers型交换器 RabbitMQ在概念上由三部分组成&#xff1a; 交换器&#xff08;Exchange&#xff09;&#xff1a;负责接收消息发布者发布消息的结构&#xff0c;同时它会根据“绑定关系”&#xff08;Ba…

52【场景作图】空间感

参考 场景绘制&#xff0c;画面空间感如何拉开&#xff1f;分分钟就能学会的场景优化思路更新啦&#xff01;_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1pa411J7Ps/?spm_id_from333.337.search-card.all.click&vd_source20db0c4e2d303527ed13c4b9cdf698ec 1 …

生活实用口语柯桥成人外语培训机构“客服”用英文怎么说?

● 01. “客服”英语怎么说&#xff1f; ● 我们都知道“客服”就是“客户服务”&#xff0c; 所以Customer Service就是#15857575376客服的意思。 但是这里的“客服”指代的不是客服人员&#xff0c; 而是一种Service服务。 如果你想要表达客服人员可以加上具体的职位&a…

Java宝藏实验资源库(1)文件

一、实验目的 掌握文件、目录管理以及文件操作的基本方法。掌握输入输出流的基本概念和流处理类的基本结构。掌握使用文件流进行文件输入输出的基本方法。 二、实验内容、过程及结果 1.显示指定目录下的每一级文件夹中的.java文件 运行代码如下 &#xff1a; import java.io.…

[C++][数据结构][图][中][图的遍历][最小生成树]详细讲解

目录 1.图的遍历1.广度优先遍历2.深度优先遍历 2.最小生成树1.Kruskal算法2.Prim算法 1.图的遍历 给定一个图G和其中任意一个顶点 v 0 v_0 v0​&#xff0c;从 v 0 v_0 v0​出发&#xff0c;沿着图中各边访问图中的所有顶点&#xff0c;且每个顶 点仅被遍历一次 “遍历”&…

# [0619] Task01 绪论、马尔可夫过程、动态规划

easy-rl PDF版本 笔记整理 P1 - P2 joyrl 比对 补充 P1 - P3 相关 代码 整理 最新版PDF下载 地址&#xff1a;https://github.com/datawhalechina/easy-rl/releases 国内地址(推荐国内读者使用)&#xff1a; 链接: https://pan.baidu.com/s/1isqQnpVRWbb3yh83Vs0kbw 提取码: us…

lib9-03 配置基于时间的 ACL

实验&#xff1a;配置基于时间的 ACL 1、实验目的 通过本实验可以掌握定义 time-range 的方法基于时间 ACL 的配置和调试方法 2、实验拓扑 实验拓扑如下图所示。本实验要求只允许主机 PC1 在周一到周五每天的 8&#xff1a;00-17&#xff1a;00 访问路由器 R3 的Telnet 服务…

Python的三种方式显示图片

from PIL import Image import numpy as np im Image.open("img.png") #方法一&#xff1a;使用PIL库显示图片 a np.array(im) imImage.fromarray(a) im.show() import matplotlib.pyplot as plt #方法二&#xff1a;使用matplotlib库显示图片 plt.imshow(a) plt.s…

Covalent实现对1000亿笔链上交易解析,支持AI长期数据可用性

在区块链与人工智能&#xff08;AI&#xff09;交汇处&#xff0c;讨论往往集中于去中心化推理和去中心化训练等方面。然而&#xff0c;这一数据的关键组成部分却一直未得到足够的重视。一个主要问题是&#xff1a;我们如何保护 AI 模型中的数据不受偏见和操纵的影响&#xff1…