I have some widgets in a SliverList that I don't want to lose state when I scroll offscreen. According to the docs, "...children in lazy list are wrapped in AutomaticKeepAlive widgets so that children can use KeepAliveNotifications to preserve their state when they would otherwise be garbage collected off-screen.", and my question is, how do I send a KeepAliveNotification? I've failed to understand the docs and have been unable to find any examples of its usage.
Where do I get or create the Listenable? In my app, when a user taps the section header it expands and changes alignment from horizontal to vertical. The state is lost when the user scrolls further down the page. Example of code below (removed some code that was irrelevant to the question to reduce clutter).
class Page extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new DefaultTabController(
length: choices.length,
child: new Scaffold(
body: new CustomScrollView(slivers: <Widget>[
new SliverAppBar(
title: new Container(
child: new TabBar(
tabs: choices.map((Choice choice) {
return new Tab(
text: choice.title,
icon: new Image.asset(choice.icon, height:22.0),
);
}).toList(),
)),
),
new SliverList(delegate:new SliverChildListDelegate([
// Widget that I want to KeepAlive
new TrendingArticles(),
//Other widgets
])),
]),
),
),
);
}
}
//Widget that I want to KeepAlive
class TrendingArticles extends StatefulWidget{
const TrendingArticles({ Key key }) : super(key: key, );
@override
_TrendingArticlesState createState() => new _TrendingArticlesState();
}
class _TrendingArticlesState extends State<TrendingArticles> {
List<Article> articles = [];
_getArticles() async {
//Code for getting articles
}
@override
initState(){
super.initState();
_getArticles();
}
void _handleSize(){
//Handles changing orientation and size of widget
}
@override
Widget build(BuildContext context) {
return new Container(
height:sectionHeight,
child: new Column(children: <Widget>[
new SectionHeader(title: "Articles", onTap:_handleSize,alignment:headerAlignment),
new Container(
height:sectionHeight - 55,
child: new ListView(
scrollDirection: scrollDirection,
children: articles.map((Article article) {
return new ArticleCard(
height: cardHeight,
article: article,
onBannerTap: (Article article) {
setState(() {
article.isFavorite = !article.isFavorite;
});
}
);
}).toList(),
),
),
]));
}
}
As mentioned here, you must add AutomaticKeepAliveClientMixin
to the State class of your sliver list delegate child, you want to keep that state. In your example it is _TrendingArticlesState
Remember to call super.build(context);
in the build
method of your _TrendingArticlesState
class.
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