Flutter-插件 scroll-to-index 实现 listView 滚动到指定索引位置

news2025/1/3 11:12:26

请添加图片描述
scroll-to-index

简介

scroll_to_index 是一个 Flutter 插件,用于通过索引滚动到 ListView 中的某个特定项。这个库对复杂滚动需求(如动态高度的列表项)非常实用,因为它会自动计算需要滚动的目标位置。

使用

  1. 安装插件
flutter pub add scroll_to_index
  1. 导入包
import 'package:scroll_to_index/scroll_to_index.dart';
  1. 初始化控制器
    使用 AutoScrollController 来控制滚动。AutoScrollController 是插件提供的增强版本,它支持滚动到指定索引的功能。

  2. 为列表项添加标识
    通过 AutoScrollTag 为每个列表项添加滚动标签。

  3. 调用滚动方法
    使用 controller.scrollToIndex 方法滚动到指定的索引。

示例代码

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

class ScrollToIndexExample extends StatefulWidget {
  @override
  _ScrollToIndexExampleState createState() => _ScrollToIndexExampleState();
}

class _ScrollToIndexExampleState extends State<ScrollToIndexExample> {
  late AutoScrollController controller;
  final randomHeights = List<double>.generate(20, (index) => 50.0 + (index % 5) * 30.0);

  @override
  void initState() {
    super.initState();
    controller = AutoScrollController(); // 初始化 AutoScrollController
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  Future<void> scrollToIndex(int index) async {
    await controller.scrollToIndex(
      index,
      preferPosition: AutoScrollPosition.begin, // 滚动目标位置(begin, middle, end)
    );
    controller.highlight(index); // 高亮滚动到的项(可选)
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scroll To Index Example'),
      ),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () => scrollToIndex(10), // 滚动到第10项
            child: Text('滚动到第10项'),
          ),
          Expanded(
            child: ListView.builder(
              controller: controller, // 使用 AutoScrollController
              itemCount: randomHeights.length,
              itemBuilder: (context, index) {
                return AutoScrollTag(
                  key: ValueKey(index), // 为每个项设置唯一的 Key
                  controller: controller,
                  index: index,
                  child: Container(
                    margin: const EdgeInsets.symmetric(vertical: 5.0),
                    height: randomHeights[index],
                    color: Colors.blue[(index % 9 + 1) * 100],
                    alignment: Alignment.center,
                    child: Text('Item $index', style: TextStyle(color: Colors.white, fontSize: 18)),
                  ),
                  highlightColor: Colors.yellow.withOpacity(0.5), // 滚动时的高亮颜色
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

实现原理

1. 索引与视图的绑定
• AutoScrollTag 负责注册每个列表项的索引及其对应的 State。
• AutoScrollController 持有一个 tagMap,这是一个 Map<int,AutoScrollTagState>,记录每个索引和对应的渲染状态。

2. 滚动到指定索引
核心方法是 scrollToIndex:

Future scrollToIndex(int index,
    {Duration duration: scrollAnimationDuration,
    AutoScrollPosition? preferPosition});

滚动方法的源码:

  RevealedOffset? _offsetToRevealInViewport(int index, double alignment) {
    final ctx = tagMap[index]?.context;
    if (ctx == null) return null;

    final renderBox = ctx.findRenderObject()!;
    assert(Scrollable.of(ctx) != null);
    final RenderAbstractViewport viewport =
        RenderAbstractViewport.of(renderBox)!;
    final revealedOffset = viewport.getOffsetToReveal(renderBox, alignment);

    return revealedOffset;
  }

关键实现详解
2.1 获取目标项的 context

final ctx = tagMap[index]?.context;
if (ctx == null) return null;
•	tagMap:存储索引和其对应的 AutoScrollTagState。
•	context:通过目标项的 State 获取其 BuildContext,用于访问渲染对象。

2.2 获取渲染对象

final renderBox = ctx.findRenderObject()!;

• findRenderObject:从 context 获取目标项的 RenderObject。
• RenderBox:表示目标项的渲染边界,用于计算其在视图中的位置。

2.3 获取视图范围

final RenderAbstractViewport viewport = RenderAbstractViewport.of(renderBox)!;

RenderAbstractViewport.of(renderBox):
• 获取目标项所属的 Viewport(视图),如 ListView 的可滚动区域。
• RenderAbstractViewport 是 Flutter 渲染层的抽象类,用于处理滚动和可见区域计算。

2.4 计算偏移量

final revealedOffset = viewport.getOffsetToReveal(renderBox, alignment);

viewport.getOffsetToReveal:
• 计算目标项(renderBox)相对于视图的滚动偏移量。
• 偏移量根据 alignment 决定,确保目标项按照指定对齐方式显示。

3. 视图边界处理
AutoScrollController 提供了视图边界计算功能,确保滚动时能够正确定位组件的可见区域。
相关属性:

ViewportBoundaryGetter viewportBoundaryGetter;
AxisValueGetter beginGetter;
AxisValueGetter endGetter;

viewportBoundaryGetter:
用于获取视图的边界范围,支持处理额外的遮挡组件(如固定头部或底部)。

beginGetter 和 endGetter:
根据滚动方向(水平或垂直),分别获取组件的起始和结束位置。

原理总结

  1. 绑定关系:
    • 通过 tagMap 确定目标索引和对应的渲染对象。
  2. 偏移计算:
    • 借助 RenderAbstractViewport.getOffsetToReveal,计算目标项相对于视图的偏移量。
  3. 滚动控制:
    • 调用 ScrollController.animateTo 方法将视图滚动到计算的偏移量位置,实现精准对齐。

感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XIAO Esp32 S3 轻松发送 HTTP 请求,打造智能物联网应用

让物联网更智能,连接更便捷! ESP32 是一款高性能的物联网开发平台,它不仅支持 Wi-Fi 和蓝牙,还是实现各种智能设备连接和控制的理想选择。今天,我们为你展示如何利用 ESP32 发送 HTTP 请求,轻松实现设备间的数据传输和远程控制。 为什么选择 ESP32 发送 HTTP 请求? 强大…

Unity中实现转盘抽奖效果(一)

实现思路&#xff1a; 旋转转盘的z轴&#xff0c;开始以角加速度加速到角速度最大值&#xff0c;结束的时候&#xff0c;以角加速度减速使角速度减少到0&#xff0c;然后转盘z轴旋转的角度就是加上每秒以角速度数值大小&#xff0c;为了使角度不能一直增大&#xff0c;对360度…

Postman[8] 断言

1.常见的断言类型 status code: code is 200 //检查返回的状态码是否为200 Response body&#xff1a; contain string //检查响应中包含指定字符串包含指定的值 response body:json value check/ /检查响应中其中json的值 Response body&#xff1a; is equal to string …

教程:从pycharm基于anaconda构建机器学习环境并运行第一个 Python 文件

1. 安装 PyCharm 访问 PyCharm 官方网站&#xff1a;https://www.jetbrains.com/pycharm/。下载社区版&#xff08;免费&#xff09;或专业版&#xff08;收费&#xff0c;提供更多功能&#xff09;。按照操作系统的安装指导安装 PyCharm。安装后打开 PyCharm&#xff0c;并根…

记录一下图像处理的基础知识

记录一下自己学习的图像处理的基础知识。 一、图像的文件格式以及常用的图像空间 1、文件格式 常见的图像文件格式有 jpg, png, bmp, gif &#xff08;1&#xff09;jpg&#xff1a;有损压缩算法&#xff0c;大幅减小文件大小&#xff0c;便于存储和传输&#xff0c;兼容性…

0030.停车场车位预约管理系统+论文

一、系统说明 基于springbootvueelementui开发的停车场车位预约管理系统,系统功能齐全, 代码简洁易懂&#xff0c;适合小白学编程。 二、系统架构 前端&#xff1a;vue| elementui 后端&#xff1a;springboot | mybatis 环境&#xff1a;jdk1.8 | mysql8.0 | maven 三、代…

SpringCloudAlibaba实战入门之路由网关Gateway断言(十二)

上一节课中我们初步讲解了网关的基本概念、基本功能,并且带大家实战体验了一下网关的初步效果,这节课我们继续学习关于网关的一些更高级有用功能,比如本篇文章的断言。 一、网关主要组成部分 上图中是核心的流程图,最主要的就是Route、Predicates 和 Filters 作用于特定路…

Postman[4] 环境设置

作用&#xff1a;不同的环境可以定义不同的参数&#xff0c;在运行请求时可以根据自己的需求选择需要的环境 1.创建Environment 步骤&#xff1a; Environment-> ->命名->添加环境变量 2.使用Environment 步骤&#xff1a;Collection- >右上角选择需要的环境

【PCIe 总线及设备入门学习专栏 4.5 -- PCIe Message and PCIe MSI】

文章目录 PCIe Message 与 MSIPCIe Message 和 MSI 的作用与关系MSI 的配置与寄存器MSI 和 ARM GIC 的关系示例&#xff1a;MSI 在 ARM GIC 的实际应用总结 PCIe Message 与 MSI 本文将介绍 PCIe message 的作用以及message 与 MSI 的关系&#xff0c;再介绍 MSI 如何配置以及…

jquery-validate在前端数据校验中的应用以及remote异步调用实践-以若依为例

目录 前言 一、关于Jquery Validate组件 1、validate是什么 2、内置验证方式及触发方式 3、自定义验证规则 二、基本验证实战以及Remote验证 1、基本验证实现 2、remote校验方式 三、总结 前言 随着技术的不断演进&#xff0c;在我们的日常开发过程中&#xff0c;大家一…

连锁餐饮行业数据可视化分析方案

引言 随着连锁餐饮行业的迅速发展&#xff0c;市场竞争日益激烈。企业需要更加精准地把握运营状况、消费者需求和市场趋势&#xff0c;以制定科学合理的决策&#xff0c;提升竞争力和盈利能力。可视化数据分析可以帮助连锁餐饮企业整合多源数据&#xff0c;通过直观、动态的可…

WPF 样式

WPF 有自己的样式设置系统&#xff0c;也自带类似 Winform 的默认样式。默认样式比较一般&#xff0c;我们可以使用下面几种方式自定义好看的 wpf 样式。 1. 本地直接设置 比如更改按钮的背景色和字体颜色&#xff0c; <Grid><StackPanel Orientation"Horizon…

RabbitMQ实现生产者消费者

一.启动MQ 注意管理员身份进入cmd才行,我这里是在本地安装的MQ,推荐使用虚拟机安装 二.思路 官方解释RabbitMQ结构: 自我理解RabbitMQ结构: 其实RabbitMQ的服务器就像邮局一样,我们的生产者和消费者对于这个服务器来说都是消费者,因为服务器都可以向两者发送消息 环境准备 …

虚拟机用网线连其他设备(ROS多机网络配置)

电脑配置 把局域网的网线插入电脑&#xff0c;点击这边 配置以太网的IP 比如说我ROS主机的IP想设为192.168.144.10&#xff0c;那我笔记本的以太网IP可以设为192.168.144.8。 假设还有另外一个电脑&#xff08;ROS从机&#xff09;&#xff0c;他的IP被设置未192.168.144.4…

VIM: Vision Mamba基于双向状态空间模型的高效视觉表示学习

这篇文章的主要内容可以概括如下&#xff1a; 背景与动机&#xff1a; 近年来&#xff0c;状态空间模型&#xff08;SSM&#xff09;在长序列建模中展现出巨大潜力&#xff0c;尤其是Mamba模型在硬件感知设计上的高效性。 然而&#xff0c;现有的SSM模型在处理视觉数据时面临…

整合版canal ha搭建--基于1.1.4版本

开启MySql Binlog&#xff08;1&#xff09;修改MySql配置文件&#xff08;2&#xff09;重启MySql服务,查看配置是否生效&#xff08;3&#xff09;配置起效果后&#xff0c;创建canal用户&#xff0c;并赋予权限安装canal-admin&#xff08;1&#xff09;解压 canal.admin-1…

tokenizer、tokenizer.encode、tokenizer.encode_plus比较

一、概念 在我们使用Transformers库进行自然语言处理任务建模的过程中&#xff0c;基本离不开Tokenizer类。我们需要这些Tokenizer类来帮助我们加载预训练模型的分词模块&#xff0c;并将文本转化为预训练模型可接受的输入格式。 而在实际建模的实践中&#xff0c;我们参考优秀…

基于深度学习(HyperLPR3框架)的中文车牌识别系统-搭建开发环境

本篇内容为搭建开发环境。包括&#xff1a;python开发环境&#xff0c;Qt/C开发环境&#xff0c;以及用到的各个库的安装和配置。 一、Python开发环境搭建与配置 1、下载并安装Anaconda 我没有用最新的版本&#xff0c;安装的是 Anaconda3-2021.05-Windows-x86_64.exe&#…

Secured Finance 与 Parasail 在流动性质押领域开展合作

Secured Finance 宣布与 Parasail 达成战略合作&#xff0c;标志着生态在推进 DePIN 及人工智能生态系统能力的重要里程碑。此次合作将 Parasail 卓越的质押方案与 Secured Finance 在去中心化贷款和稳定币协议方面的专业能力相结合&#xff0c;为 Filecoin 生态系统内的创新金…

计算机网络 (8)物理层的传输方式

一、串行传输与并行传输 串行传输 定义&#xff1a;串行传输是一种数据传输方式&#xff0c;指的是逐位地按照顺序传输数据。在串行传输中&#xff0c;数据位逐个按照一定的顺序进行传输&#xff0c;可以通过单条线路或信道进行。特点&#xff1a; 逐位传输&#xff1a;串行传输…