BottomNavigationBar page change causing StreamBuilder data reload
Asked Answered
R

1

6

Inside BottomNavigation I have 2 page. 1st Page loading data from the network and showing in SliverList and In another page showing static list data.

After moving from 1st to 2nd page then 1st page all network data are gone. I have used PageStorageKey but still, it's not working. but the 2nd page never reloaded.

Why is 1st page not saving its state which has StreamBuilder?

My code:

Bottom Navigation Page:

class MainActivity extends StatefulWidget {
  @override
  _MainActivityState createState() => _MainActivityState();
}

class _MainActivityState extends State<MainActivity> {

  final Key keyHome = PageStorageKey('pageHome');
  final Key keyChat = PageStorageKey('pageChat');

  int currentTab = 0;

  HomePage home;
  Chat chat;
  List<Widget> pages;
  Widget currentPage;

  final PageStorageBucket bucket = PageStorageBucket();
  @override
  void initState(){
    home = HomePage(

      key: keyHome,
    );
    chat = Chat(
      key: keyChat,
    );
    pages = [home, chat];
    currentPage = home;

    super.initState();
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageStorage(
        child: currentPage,
        bucket: bucket,),
      //Bottom Navigation Bar added
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentTab,
        onTap: (int index){
          setState(() {
            currentTab = index;
            currentPage = pages[index];
          });
        },
        type: BottomNavigationBarType.fixed,
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(icon: Icon(Icons.chat), title: Text('Chat')),
          BottomNavigationBarItem(
              icon: Icon(Icons.payment), title: Text('Pay')),
          BottomNavigationBarItem(
              icon: Icon(Icons.account_circle), title: Text('Me')),
        ],
        //currentIndex: _selectedIndex,
        fixedColor: Colors.deepPurple,
      ),
    );
  }
}

Home Page:

class HomePage extends StatefulWidget { HomePage({ Key key, }) : super(key: key); @override _HomePageState createState() => _HomePageState(); }

class _HomePageState extends State<HomePage>{
  @override
  Widget build(BuildContext context) {

    final NewsCatalogBlog newsBloc = BlocProvider.of<NewsCatalogBlog>(context);

    //bloc.fetchAllNews();
    return Scaffold(
      appBar: PreferredSize(child: HomePageGradientAppBar(),
        preferredSize: const Size.fromHeight(100.0),),

      body: StreamBuilder(
        stream: newsBloc.outNewsList,
        builder: (context, AsyncSnapshot<List<Data>> snapshot) {
          Widget newsList;

          newsList = new SliverList(
            delegate: new SliverChildBuilderDelegate((context,index){
              print("$index");
              return NewsListRow(snapshot.data, newsBloc, index);
            },
                childCount: (snapshot.data == null ? 0 : snapshot.data.length) + 30),
          );

          return new CustomScrollView(
            slivers: <Widget>[
              SliverToBoxAdapter(child: TabPanel(),),
              SliverToBoxAdapter(child: UrlButtonPanel(),),
              SliverToBoxAdapter(child: ChatNowAd(),),
              newsList,
            ],
          );
        },
      ),
    );
  }
}

Chat Page:

class Chat extends StatelessWidget { Chat({ Key key, }): super (key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemExtent: 250.0,
      itemCount: 20,
      itemBuilder: (context, index) => Container(
        padding: EdgeInsets.all(10.0),
        child: Material(
          elevation: 4.0,
          borderRadius: BorderRadius.circular(5.0),
          color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,
          child: Center(
            child: Text('Mir{$index}'),
          ),
        ),
      ),
    );
  }


}
Raffo answered 8/12, 2018 at 12:34 Comment(4)
check -AutomaticKeepAliveClientMixin - docs.flutter.io/flutter/widgets/…Musetta
same result. My scroll position is saved but list data reloading again.Raffo
you need to keep your build method pure - check great answer by remi - https://mcmap.net/q/99528/-how-to-deal-with-unwanted-widget-buildMusetta
I have pagination system in streambuilder. how to optimize it for bottomNavigationBar?Raffo
P
4

Better way is to use IndexedStack instead of PageStorage or AutomaticKeepAliveClientMixin.

 class _MainActivityState extends State<MainActivity> {

  int _selectedPage = 0;
  List<Widget> pageList = List<Widget>();

  @override
  void initState() {
    pageList.add(HomePage());
    pageList.add(ChatPage());
    super.initState();
  }

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: IndexedStack(
        index: _selectedPage,
        children: pageList,
      ),
      //Bottom Navigation Bar added
      bottomNavigationBar: BottomNavigationBar(
    .....

**IndexedStack Widget is sub-class of Stack Widget

It shows single child from list of provided Childs. Its size as big as largest child. It keep state of all Childs.**

Prolific answered 22/9, 2020 at 6:11 Comment(2)
can you please elaborate your answer with navigation page change action?Raffo
medium.com/flutter/…Hosbein

© 2022 - 2024 — McMap. All rights reserved.