Issue
I am slivers to my application.
What I want to do is when the SliverAppBar is fully scrolled up I want to show a different Widget inside it.
Can anyone provide some help on this?
I understand using SliverPersistentHeader something like this can be done. But is there a way to show and hide the header based on where it is?
class SliversBasicPage extends StatelessWidget {
_isPinned() {
return false;
}
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
floating: false,
expandedHeight: 120.0,
flexibleSpace: FlexibleSpaceBar(
title: _isPinned() ? Text('PINNED') : Text('NOT PINNED'),
),
),
SliverFixedExtentList(
itemExtent: 50,
delegate: SliverChildListDelegate([
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.blue),
]),
),
],
);
}
}
Solution
There are a couple of things you will need to do. Firstly, you’ll need a statefull widget so that you can change the state of the pinned flag and have the UI rebuild. Secondly, you’ll need a ScrollController
to listen for the scrolling state and toggle the value is isPinned
depending upon the collapsed/non-collapsed state of the app bar.
The controller could look something like this:
final ScrollController _sliverScrollController = ScrollController();
var isPinned = false;
.....
@override
void initState() {
super.initState();
_sliverScrollController.addListener(() {
if (!isPinned &&
_sliverScrollController.hasClients &&
_sliverScrollController.offset > kToolbarHeight) {
setState(() {
isPinned = true;
});
} else if (isPinned &&
_sliverScrollController.hasClients &&
_sliverScrollController.offset < kToolbarHeight) {
setState(() {
isPinned = false;
});
}
});
}
.....
Add this controller to the controller parameter in CustomScrollView.
Answered By – amugofjava
Answer Checked By – Cary Denson (FlutterFixes Admin)