简介
一个可以嵌在另一个滚动视图中的Scroll view,本质上,他们的滚动是连接着的
- 最常见的用例就是一个可滚动的视图,包含一个 flexible SliverAppBar,并且包含TabBar和TabBarView
- 在普通的ScrollView中包含一系列 slivers ,会出现滚动冲突的问题
- NestedScrollView 通过为外部ScrollView和内部的ScrollViews提供自定义的ScrollController来解决滚动冲突的问题,将他们“连接”起来,以便他们滚动时看起来更像是一个整体
基本用法
Demo演示NestedScrollView最常见的使用实例
- 头部为一个SliverAppBar,折叠部分的内容都放在了flexibleSpace中
- 由 headerSliverBuilder 构建出来一个包含TabBar的SliverAppBar,并且在body中包含 TabBarView
实例演示
import 'package:flutter/material.dart';
class NestedScrollViewDemo extends StatefulWidget {
_NestedScrollViewDemoState createState() => _NestedScrollViewDemoState();
}
class _NestedScrollViewDemoState extends State<NestedScrollViewDemo>
with SingleTickerProviderStateMixin {
TabController _tabController;
ScrollController _scrollViewController;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 2);
_scrollViewController = ScrollController(initialScrollOffset: 0.0);
}
@override
void dispose() {
_tabController.dispose();
_scrollViewController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
height: 700.0,
child: Scaffold(
body: NestedScrollView(
controller: _scrollViewController,
headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text('Tab Controller'),
pinned: true,
floating: true,
forceElevated: boxIsScrolled,
expandedHeight: 200.0,
flexibleSpace: Container(
child: Image.asset(
'assets/images/timg.jpeg',
width: double.infinity,
repeat: ImageRepeat.repeat,
height: double.infinity,
),
),
bottom: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
text: "Home",
icon: Icon(Icons.home),
),
Tab(
text: "Help",
icon: Icon(Icons.help),
),
],
),
)
];
},
body: TabBarView(
children: <Widget>[
PageOne(),
PageTwo(),
],
controller: _tabController,
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.control_point),
onPressed: () {
_tabController.animateTo(1,
curve: Curves.bounceInOut,
duration: Duration(milliseconds: 10));
_scrollViewController
.jumpTo(_scrollViewController.position.maxScrollExtent);
},
),
),
);
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Image.asset(
'assets/images/food06.jpeg',
width: 300.0,
fit: BoxFit.contain,
),
Image.asset(
'assets/images/food02.jpeg',
width: 300.0,
fit: BoxFit.contain,
),
],
));
}
}
class PageTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemExtent: 250.0,
itemBuilder: (context, index) => Container(
padding: EdgeInsets.all(10.0),
child: Material(
elevation: 4.0,
borderRadius: BorderRadius.circular(5.0),
color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,
child: Center(
child: Text(index.toString()),
),
),
),
);
}
}