Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make use of KeepAliveNotification in flutter?

Tags:

flutter

dart

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(),
        ),
      ),
    ]));   
  }
}
like image 646
Christopher Thompson Avatar asked Nov 08 '22 12:11

Christopher Thompson


1 Answers

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.

like image 179
Sergey Motyrev Avatar answered Nov 26 '22 14:11

Sergey Motyrev