I am trying to place a PageView
which pages are scrollable vertically into a CustomScrollView
.
The reason for this setup is that I want to make use of SliverAppBar
. If one starts scrolling vertically, the AppBar starts shrinking and ultimately docks at the top of the screen. At the same time the currently active page's content is expanded. Once the AppBar is docked and the page's content reached it's maximum allowed size, it itself starts scrolling.
I am running into all sorts of problem, mostly issues with unbounded sizes.
The answer you've found as you've mentioned in the comments is correct. Instead of a CustomScrollView
, NestedScrollView
should be used because there are multiple scrollable views that will be managed on the screen. As mentioned in the docs, the most common use case for NestedScrollView
is a scrollable view with a flexible SliverAppBar containing a TabBar in the header - similar to your use case.
Here's a working sample based from the snippet provided in the post you've referenced.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
var _scrollController, _tabController;
@override
void initState() {
_scrollController = ScrollController();
_tabController = TabController(vsync: this, length: 2);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text(widget.title),
pinned: true,
floating: true,
snap: false,
forceElevated: innerBoxIsScrolled,
bottom: TabBar(
tabs: <Tab>[
Tab(text: "Page 1"),
Tab(text: "Page 2"),
],
controller: _tabController,
),
),
];
},
body: TabBarView(
controller: _tabController,
children: <Widget>[
_pageView(),
_pageView(),
],
),
),
);
}
_pageView() {
return ListView.builder(
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Container(
padding: EdgeInsets.all(16.0),
child: Text('List Item $index'),
),
);
},
);
}
}
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With