'How to keep the state of each page when using PageTransitionSwitcher?

I am trying to add the animation library to my project, but I am having problems. The previous code is like this

  Widget _buildScaffold(BuildContext context) {
return Scaffold(
  body: PageView.builder(itemBuilder: (context,index)=>_pageList[index]),
  extendBody: true,
  bottomNavigationBar: Opacity(
    opacity: 0.98,
    child: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        selectedItemColor: Theme.of(context).accentColor,
        currentIndex: index,
        onTap: (index) {
          setState(() {
            this.index = index;
          });
          // _pageController.jumpToPage(index);
        },
        items: _bottomList),
  ),
);

} When I changed PageView.builder to PageTransitionSwitcher, according to the example, the value of child is _pageList[index], the animation is available, and the state is lost when switching pages. When I try to use PageView as a child, the state can be set KeepAlive is retained, but the animation disappears (because it is judged to be the same widget)

  Widget _buildScaffold(BuildContext context) {
return Scaffold(
  body: PageTransitionSwitcher(
    transitionBuilder: (
      Widget child,
      Animation<double> primaryAnimation,
      Animation<double> secondaryAnimation,
    ) {
      return FadeThroughTransition(
        animation: primaryAnimation,
        secondaryAnimation: secondaryAnimation,
        child: child,
      );
    },
    child: PageView.builder(itemBuilder: (_,index)=>_pageList[index]),
  ),
  extendBody: true,
  bottomNavigationBar: Opacity(
    opacity: 0.98,
    child: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        selectedItemColor: Theme.of(context).accentColor,
        currentIndex: index,
        onTap: (index) {
          setState(() {
            this.index = index;
          });
          // _pageController.jumpToPage(index);
        },
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.home), title: Text(I18n.of(context).home)),
          BottomNavigationBarItem(
              icon: Icon(
                CustomIcons.leaderboard,
              ),
              title: Text(I18n.of(context).rank)),
          BottomNavigationBarItem(
              icon: Icon(Icons.favorite),
              title: Text(I18n.of(context).quick_view)),
          BottomNavigationBarItem(
              icon: Icon(Icons.search),
              title: Text(I18n.of(context).search)),
          BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text(I18n.of(context).setting)),
        ]),
  ),
);

}

So, is there a way to preserve both the animation and the state of the page?



Solution 1:[1]

Here's what I did.

In your stateful widget, if you are showing a list of items in your page, you can add static variable in front of the list you wanna preserve so that it wont re fetched upon switching pages.

If you are currently using a FutureBuilder, i think you have to change to this instead because you need a static list to refer to.

  static List<YourObject> yourList = new List();


  @override
  void initState() {
    super.initState();
    //some async task to fetch data and populate yourList
    fetchData();
  }



  @override
  Widget build(BuildContext context) {
    if(yourList.length == 0){
      return CircularProgressIndicator();
    }else{
      return ListView.builder(){
        itemCount: yourList.length,
        itemBuilder: (BuildContext context, int index){
          ...yourcodehere
        }
      }
    }
  }

Solution 2:[2]

The solution is extremely simple.
Adding the following to my ListView helped for me.

key: PageStorageKey<String>('customKeyName'),

I found the solution after randomly finding an article about GlobalKey() and that it can be used to keep/restore a widgets state.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 FadhliS
Solution 2 Jeremy Caney