Reputation: 5772
I have a SliverAppBar (floating: true, pinned: false).
I want to achieve that the user has to scroll 200 pixels (or some other amount) before the SliverAppBar starts to compress/slide-up.
Upvotes: 2
Views: 1273
Reputation: 8427
The problem here is that pinned
value is not supposed to be changed. If you try to change it after scrolling 200 pixels, the SliverAppBar
would shrink suddenly.
You can check this out by running the code below:
class Buster extends StatefulWidget {
@override
_BusterState createState() => _BusterState();
}
class _BusterState extends State<Buster> {
ScrollController controller;
bool isAppBarPinned;
@override
void initState() {
super.initState();
controller = ScrollController()..addListener(onScroll);
isAppBarPinned = true;
}
void onScroll() {
if (controller.position.pixels > 200) {
if (isAppBarPinned) {
setState(() => isAppBarPinned = false);
}
} else {
if (!isAppBarPinned) {
setState(() => isAppBarPinned = true);
}
}
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
controller: controller,
slivers: [
SliverAppBar(
title: Text('Buster'),
floating: true,
pinned: isAppBarPinned,
),
SliverFixedExtentList(
itemExtent: 150,
delegate: SliverChildListDelegate(
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
.map((int index) => Center(child: Text('Item #$index')))
.toList(),
),
)
],
),
);
}
}
So I think the best option you got here is using a regular AppBar
and animate it manually with a Transform
.
Upvotes: 3