https://pub.dev/packages/extended_nested_scroll_view
中文说明:https://github.com/fluttercandies/extended_nested_scroll_view/blob/master/README-ZH.md
扩展NestedScrollView来修复了下面的问题
1.pinned的Header的问题
2.body里面TabView列表滚动同步,互相影响的问题
3.下拉刷新不能工作
4.在NestedScrollView的body中不通过设置ScrollController(设置了会跟内部Controller冲突)来完成下拉刷新,增量加载,滚动到顶部
- Flutter 扩展NestedScrollView (一)Pinned头引起的bug解决
- Flutter 扩展NestedScrollView (二)列表滚动同步解决
- Flutter 扩展NestedScrollView (三)下拉刷新的解决
安装依赖
dependencies:extended_nested_scroll_view: ^2.0.0
导入
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
示例
import 'dart:async';import 'package:app1/utils/Base.dart';import 'package:flutter/material.dart';import 'package:flutter_easyrefresh/easy_refresh.dart';import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' as extended;class NestedScrollViewPage extends StatefulWidget {@override_NestedScrollViewPageState createState() => _NestedScrollViewPageState();}class _NestedScrollViewPageState extends State<NestedScrollViewPage>with SingleTickerProviderStateMixin {TabController _tabController; //tab控制器int _tabIndex = 0; //Tab索引int _listCount = 10; //tab-列表数量int _gridCount = 10; //tab-表格数量@overridevoid initState() {super.initState();_tabController = TabController(length: 2, vsync: this);}@overridevoid dispose() {super.dispose();_tabController.dispose();}@overrideWidget build(BuildContext context) {// 在NestedScrollView当中,有2个ScrollController.// 一个是inner,一个outer。// outer是负责headerSliverBuilder里面的滚动widgets// inner是负责body里面的滚动widgets 当outer滚动到底了之后,就会看看inner里面是否有能滚动的东东,开始滚动。return extended.NestedScrollView(// 在pinnedHeaderSliverHeightBuilder回调中设置全部pinned的header的高度,// demo里面高度为 状态栏高度+SliverAppbar的高度pinnedHeaderSliverHeightBuilder: () {return MediaQuery.of(context).padding.top + kToolbarHeight;},// innerScrollPositionKeyBuilder回调中给出当前tab的key.innerScrollPositionKeyBuilder: () {if (_tabController.index == 0) {return Key('tab0');} else {return Key('tab1');}},headerSliverBuilder: (context, innerBoxIsScrolled) {return [SliverAppBar(title: Text("NestedScrollView"),pinned: true,expandedHeight: 120.0,flexibleSpace: SingleChildScrollView(physics: NeverScrollableScrollPhysics(),child: Container(),),floating: false,),];},body: Column(children: [Container(height: 50,color: Colors.green,child: TabBar(controller: _tabController,onTap: (index) {setState(() {_tabIndex = index;});},tabs: [Tab(text: 'List'),Tab(text: 'Grid'),],),),Expanded(child: IndexedStack(index: _tabIndex,children: [// TabbarView里面的列表,使用NestedScrollViewInnerScrollPositionKeyWidget包住,// 并且设置唯一key, 这个key跟列表是第几个tab有关系。extended.NestedScrollViewInnerScrollPositionKeyWidget(Key('Tab0'),EasyRefresh(child: ListView.builder(padding: EdgeInsets.all(0.0),itemBuilder: (context, index) {return Container(color: Color(Base.getRandomColor()),height: 100,child: Text('我是列表文本 ${index + 1}', textScaleFactor: 3),);},itemCount: _listCount,),onRefresh: () async {await Future.delayed(Duration(seconds: 2), () {if (mounted) {setState(() {_listCount = 10;});}});},onLoad: () async {await Future.delayed(Duration(seconds: 2), () {if (mounted) {setState(() {_listCount += 10;});}});},),),extended.NestedScrollViewInnerScrollPositionKeyWidget(Key('Tab1'),EasyRefresh(child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2,childAspectRatio: 6 / 7,),itemBuilder: (context, index) {return Container(color: Color(Base.getRandomColor()),height: 100,child: Text('我是表格文本 ${index + 1}', textScaleFactor: 2),);},itemCount: _gridCount,),onRefresh: () async {await Future.delayed(Duration(seconds: 2), () {if (mounted) {setState(() {_gridCount = 10;});}});},onLoad: () async {await Future.delayed(Duration(seconds: 2), () {if (mounted) {setState(() {_gridCount += 10;});}});},),),],),),],),);}}
