当前位置: 首页 > news >正文

Flutter中的 extended_nested_scroll_view 库:介绍与使用指南

在开发Flutter应用时,处理复杂的滚动效果是一项常见的任务。Flutter提供了NestedScrollView来实现可折叠的应用栏与滚动列表的结合,但在某些情况下,NestedScrollView可能不够强大。为了解决这些问题,我们可以使用extended_nested_scroll_view库,该库对NestedScrollView进行了扩展,提供了更多的功能和更灵活的滚动控制。

为什么选择extended_nested_scroll_view

extended_nested_scroll_view库主要解决了Flutter原生NestedScrollView在某些场景下的不足之处,以下是它的几个优点:

  • 支持TabBarView的同步滚动:在多个Tab页面之间切换时,能够保持滑动位置的一致性。
  • 提供更灵活的滚动控制:更好地处理复杂的嵌套滚动场景,如在列表头部添加自定义布局。
  • 解决内外滚动冲突:更好地处理内外滚动视图之间的滑动事件冲突。

如何使用extended_nested_scroll_view

1. 添加依赖

pubspec.yaml文件中添加extended_nested_scroll_view库的依赖:

dependencies:flutter:sdk: flutterextended_nested_scroll_view: ^最新版本号

然后运行命令安装依赖:

flutter pub get

2. 基本使用示例

下面是一个基本的extended_nested_scroll_view使用示例,它展示了如何创建一个具有可折叠AppBar和多个Tab页面的界面。

 import 'package:flutter/material.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'as extended;void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Extended Nested ScrollView Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: HomeScreen(),);}
}class HomeScreen extends StatelessWidget {Widget build(BuildContext context) {return DefaultTabController(length: 3,child: Scaffold(body: extended.ExtendedNestedScrollView(headerSliverBuilder: (context, innerBoxIsScrolled) {return [SliverAppBar(title: const Text('Extended Nested ScrollView'),pinned: true,expandedHeight: 200.0,flexibleSpace: FlexibleSpaceBar(background: Image.network('https://example.com/image.jpg',fit: BoxFit.cover,),),bottom: const TabBar(tabs: [Tab(icon: Icon(Icons.directions_car), text: 'Car'),Tab(icon: Icon(Icons.directions_transit), text: 'Transit'),Tab(icon: Icon(Icons.directions_bike), text: 'Bike'),],),),];},body: TabBarView(children: [_buildTabContent('Car Page'),_buildTabContent('Transit Page'),_buildTabContent('Bike Page'),],),),),);}Widget _buildTabContent(String title) {return extended.ExtendedVisibilityDetector(uniqueKey: Key(title),child: ListView.builder(key: PageStorageKey<String>(title),itemCount: 30,itemBuilder: (context, index) {return ListTile(title: Text('$title Item $index'),);},),);}
}

3. 解释示例

在上面的示例中,我们使用了extended.ExtendedNestedScrollView代替Flutter自带的NestedScrollView。关键代码如下:

  • headerSliverBuilder:用于构建头部可滚动部分,包括SliverAppBar
  • TabBarView:配合TabBar实现多个选项卡视图。
  • NestedScrollViewInnerScrollPositionKeyWidget:用于确保每个Tab页面的ListView具有唯一的滚动位置,这样可以在Tab切换时保持滚动状态。

4. 进阶使用:同步Tab页面的滚动位置

extended_nested_scroll_view提供了更为高级的功能,例如在不同Tab页面之间同步滚动位置。我们可以使用TabBarViewcontroller属性结合extended.ExtendedNestedScrollViewcontroller来实现这一点。

import 'package:flutter/material.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'as extended;void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Extended Nested ScrollView Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: HomeScreen(),);}
}class HomeScreen extends StatefulWidget {_HomeScreenState createState() => _HomeScreenState();
}class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {late TabController _tabController;void initState() {super.initState();_tabController = TabController(length: 3, vsync: this);}Widget build(BuildContext context) {return Scaffold(body: extended.ExtendedNestedScrollView(headerSliverBuilder: (context, innerBoxIsScrolled) {return [SliverAppBar(title: const Text('Extended Nested ScrollView'),pinned: true,expandedHeight: 200.0,flexibleSpace: FlexibleSpaceBar(background: Image.network('https://example.com/image.jpg',fit: BoxFit.cover,),),bottom: TabBar(controller: _tabController,tabs: const [Tab(icon: Icon(Icons.directions_car), text: 'Car'),Tab(icon: Icon(Icons.directions_transit), text: 'Transit'),Tab(icon: Icon(Icons.directions_bike), text: 'Bike'),],),),];},body: TabBarView(controller: _tabController,children: [_buildTabContent('Car Page'),_buildTabContent('Transit Page'),_buildTabContent('Bike Page'),],),),);}Widget _buildTabContent(String title) {return extended.ExtendedVisibilityDetector(uniqueKey: Key(title),child: ListView.builder(key: PageStorageKey<String>(title),itemCount: 30,itemBuilder: (context, index) {return ListTile(title: Text('$title Item $index'),);},),);}
}

常见问题和解决方案

1. 滚动位置同步问题

在使用extended_nested_scroll_view时,确保每个子列表视图使用ExtendedVisibilityDetector包裹,并且使用唯一的Key以防止滚动位置错误。

2. Tab切换时滚动状态恢复

extended_nested_scroll_view可以很好地管理Tab页面之间的滚动状态切换,如果遇到问题,可以检查PageStorageKey的使用是否正确。

结论

extended_nested_scroll_view库提供了更强大和灵活的滚动布局解决方案,使得在Flutter中实现复杂的UI设计更加容易。如果你的应用需要处理复杂的滚动场景,或者需要在多个Tab页面之间保持一致的滚动体验,那么extended_nested_scroll_view是一个非常不错的选择。

相关文章:

Flutter中的 extended_nested_scroll_view 库:介绍与使用指南

在开发Flutter应用时&#xff0c;处理复杂的滚动效果是一项常见的任务。Flutter提供了NestedScrollView来实现可折叠的应用栏与滚动列表的结合&#xff0c;但在某些情况下&#xff0c;NestedScrollView可能不够强大。为了解决这些问题&#xff0c;我们可以使用extended_nested_…...

Elasticsearch 综合搜索案例解析

Elasticsearch 是一个功能强大的搜索引擎&#xff0c;它不仅支持全文搜索&#xff0c;还提供了排序、分页、高亮显示等多种搜索结果处理功能。通过综合使用这些功能&#xff0c;我们可以构建出丰富而高效的搜索应用。本文将通过一个具体的案例&#xff0c;介绍如何在 Elasticse…...

Web存储革命:揭秘JavaScript的会话存储(sessionStorage)

标题&#xff1a;Web存储革命&#xff1a;揭秘JavaScript的会话存储&#xff08;sessionStorage&#xff09; 在当今的Web开发中&#xff0c;状态管理和数据持久化是构建交互式应用的关键。JavaScript提供了多种客户端存储解决方案&#xff0c;其中会话存储&#xff08;sessio…...

基于python的百度迁徙迁入、迁出数据分析(九)

副标题&#xff1a;从百度迁徙数据看——人口虹吸效应 人口虹吸效应&#xff1a;人口虹吸效应是指大城市或中心城市因其经济、文化、教育、医疗等资源的优势&#xff0c;吸引周边地区的人口、资本和其他资源向其集中的一种现象。这种效应在城市化进程中尤其明显&#xff0c;通…...

2025上海礼品展 华东礼品工艺品展览会

2025第25届上海国际礼品及家居用品展 在璀璨繁华的上海&#xff0c;一场盛大的礼品盛宴即将拉开帷幕。2025年上海国际礼品及 家居用品展览会(简称“华礼展”)&#xff0c;作为华东地区乃至全国范围内备受瞩目的礼 品行业盛会&#xff0c;将于2025年6月29日至7月1日在上海新国…...

Flink开发(一):概述与基础

目录 1. Flink概述 1.1 什么是Flink&#xff1f; 1.2 Flink的主要特点 2. Flink的核心组件 2.1 Flink架构 2.2 数据流模型 3. Flink的基础应用 3.1 开发环境配置 3.3 数据源和数据接收器 4. Flink的高级功能 4.1 状态管理与容错 4.2 窗口操作 5. Flink的应用场景 …...

GD32E503实现串口中断收发功能

如有技术问题及技术需求请加作者微信! 源码下载链接:代码下载 亲测可用实现GD32E503库函数串口数据收发功能: #include "gd32e50x.h" #include "gd32e503v_eval.h" #include "systick.h" #include <stdio.h> #include "user_uart…...

照片怎么提取文字?分享5种简单好用的提取方法

在我们日常的学习或者是办公中&#xff0c;往往会使用到大量的图片文件&#xff0c;而在这些图片中往往蕴含着丰富的文字信息&#xff0c;但手动输入不仅费时费力&#xff0c;还容易出错。如果能够一键提取出图片中的文字就会大大提高工作效率&#xff0c;下面给大家分享5种提取…...

最佳云服务器推荐:三丰云免费虚拟主机和云服务器

随着云计算技术的不断发展&#xff0c;越来越多的企业和个人开始将业务迁移到云端。在这个过程中&#xff0c;选择一款稳定、高效、性价比高的云服务器至关重要。今天&#xff0c;我就为大家推荐一家备受好评的云服务器提供商——三丰云&#xff08;https://www.sanfengyun.com…...

IPKISS Tutorial 目录(目前 45 篇 持续更新中,部分教程尚未制作成目录)

IPKISS Tutorial 目录 芯片版图绘制教程IPKISS Tutorial&#xff08;5&#xff09;Basis直接创建结构&#xff08;1&#xff09;PCell&#xff08;3&#xff09;Layer and Template(Trace Template)&#xff08;2&#xff09;参数查询&#xff08;2&#xff09;Lumerical API&a…...

加强混合工作时代的组织网络安全态势

随着组织转向采用和实施混合和远程工作模式&#xff0c;网络安全的重要性从未如此重要。虽然工作场所的这种演变提供了灵活性并有望提高生产力&#xff0c;但它也带来了组织无法忽视的无数网络安全挑战。多样化工作环境的整合需要强大的安全措施、创新的保护策略和警惕的文化&a…...

vivado报错:file ended before end of clause

最近在学习Xilinx FPGA时&#xff0c;遇到 Vivado 报错如下图所示&#xff1a; 刚开始&#xff0c;看到错误是在第1行代码中出现的&#xff0c;我的第一反应是该行代码写错了&#xff0c;然后搜了搜语法&#xff0c;发现没错。 分析报错信息发现&#xff0c;该错误应该是和文件…...

基于asp.net的webform框架的校园点餐系统源码

今天给大家分享一套基于asp.net的webform框架的网页点餐系统&#xff0c;适合课程设计参考及其自己学习&#xff0c;需要的小伙伴自己参考下&#xff0c;下载链接我放在后面了 主要功功能 系统的主要功能包含&#xff1a;前端点餐页面、加入购物车、商品食物浏览、我的购 物车…...

俞敏洪,真窝囊?

文&#xff5c;琥珀食酒社 作者 | 璇子 大家都被俞敏洪骗了 当年《中国合伙人》一播出 俞敏洪竟抱怨黄晓明说&#xff1a; “你把我演得太窝囊&#xff01;” 那俞敏洪真的不窝囊吗&#xff1f; 他培养出董宇辉 让他赚了近6亿 结果人没留住、公司也送了人 还要被丈母娘…...

速盾:高防ip和cdn哪个好?

高防IP和CDN是两种常见的网站安全解决方案&#xff0c;它们在提供网站安全保护方面有着不同的优势和特点。下面&#xff0c;我们将从技术原理、性能优势和适用场景等方面进行比较&#xff0c;帮助您选择适合自己网站的解决方案。 首先&#xff0c;我们来看看高防IP的特点。高防…...

论文分享|MLLMs中多种模态(图像/视频/音频/语音)的tokenizer梳理

本文旨在对任意模态输入-任意模态输出 (X2X) 的LLM的编解码方式进行简单梳理&#xff0c;同时总结一些代表性工作。 注&#xff1a;图像代表Image&#xff0c;视频代表Video&#xff08;不含声音&#xff09;&#xff0c;音频代表 Audio/Music&#xff0c;语音代表Speech 各种…...

如何使用 Puppeteer 和 Node.JS 进行 Web 抓取?

什么是 Headlesschrome&#xff1f; Headless&#xff1f;是的&#xff0c;这意味着这个浏览器没有图形用户界面 (GUI)。不用鼠标或触摸设备与视觉元素交互&#xff0c;你需要使用命令行界面 (CLI) 来执行自动化操作。 Headlesschrome 和 Puppeteer 很多网页抓取工具都可适用…...

JDK 8 有哪些新特性?

JDK 8 引入了一系列新特性&#xff0c;主要包括&#xff1a; 1. 元空间替代了永久代 解决了永久代的内存管理、性能问题。提高了类加载器的隔离性。增强了可扩展性和跨平台性。提升了与垃圾收集器的兼容性。 因为 JDK8 要把 JRockit 虚拟机和 Hotspot 虚拟机融合&#xff0c…...

C++ Win32API 贪吃蛇游戏

程序代码&#xff1a; #include <windows.h> #include <list> #include <ctime>// 定义游戏区域大小 const int width 20; const int height 20;// 定义贪吃蛇的方向 enum Direction { UP, DOWN, LEFT, RIGHT };// 定义贪吃蛇的节点 struct SnakeNode {in…...

【Python实现代码视频/视频转字符画/代码风格视频】

该程序改良自GitHub开源项目VideoCharDraw 在源程序CharDraw_thread.py 带压缩和多线程版本字符画的基础上使用Tkinter库添加了图形化的操作&#xff0c;使用户操作体验更方便。 什么是视频字符画&#xff1f; 视频转字符画是一种将视频中的每一帧图像转换为由字符组成的图…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...