0

I'm working with FutureBuilder and I initialize _future in InitState as mentioned here. Despite this, FutureBuilder re-build itself every time I switch page with the BottomNavigationBar.

Code Sample:

class _HomeViewState extends State<HomeView> {

  late final Future<List<DocumentSnapshot<Object?>>> _futureSerieA;



  @override
  void initState() {

    super.initState();
    _futureSerieA = getScheduled("Serie A");

  }

  @override
  Widget build(BuildContext context) {
    return SizedBox.expand(
      child: SingleChildScrollView(
        child: Column(
          children: [


            Padding(
              padding: const EdgeInsets.fromLTRB(0,0,0,0),
              child: Container(
                decoration: const BoxDecoration(

                  border: Border(

                    bottom: BorderSide(color: Colors.transparent)
                  )
                ),
                child: Theme(
                  data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
                  child: FutureBuilder(
                    future: _futureSerieA,
                    builder: (context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {

                      if (snapshot.hasData) {
                        List<String> scheduled = [];

                        for (var DOC in snapshot.data!) {
                          scheduled.add(DOC.id);
                        }
                        return ...

How could I disable FutureBuilder re-build when browsing between pages of BottomNavigationBar?

BottomNavBar:

class _LoggedHandleState extends State<LoggedHandle> {

 
  );
  double height = AppBar().preferredSize.height;

  int _selectedPage = 1;
  final _pageOptions = [
    const BetView(),
    const HomeView(),
    const UserView()
  ];




  @override
  Widget build(BuildContext context) {
    return Scaffold(

      ...
      ),
    

      bottomNavigationBar: BottomNavigationBar(
          unselectedItemColor: Colors.white60,
          backgroundColor: Colors.red,
          selectedItemColor: Colors.white,
          currentIndex: _selectedPage,
          onTap: (int index) {
            setState(() {
              _selectedPage = index;
            });
          },
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.receipt),
              label: 'Schedina',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.account_circle),
              label: 'Account',
            ),
          ]),

      body: _pageOptions[_selectedPage],
    );
  }

 
}

faccio
  • 652
  • 3
  • 16

1 Answers1

0

When browsing between pages of bottom navigation bar, your state is not maintained. This behaviour causes the widget to rebuild every time.

You can use Indexed Stack https://api.flutter.dev/flutter/widgets/IndexedStack-class.html

  @override
      Widget build(BuildContext context) {
        return Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            onTap: (index) {
              setState(() {
                current_tab = index;
              });
            },
            currentIndex: current_tab,
            items: [
              BottomNavigationBarItem(
                ...
              ),
              BottomNavigationBarItem(
                ...
              ),
            ],
          ),
          body: IndexedStack(
            children: <Widget>[
              PageOne(),
              PageTwo(),
            ],
            index: current_tab,
          ),
        );
      }

Although this is the best solution, it will load all your widgets once the IndexedStack is loaded. I found a Lazy Loading Indexed Stack util to load your widgets when and only the first time they are created https://github.com/okaryo/lazy_load_indexed_stack

  • Thank you, I'm going to test this solution. Just I did'nt understand very well the last part of your answer: why should I need lazy_load_indexed_stack? – faccio Jul 22 '22 at 16:13
  • Because all of your widgets are going to be built at the same time when IndexedStack is placed in the widget tree, maybe this is not your case but if you have a lot of widgets or your widgets are heavy, they will be loaded at the same time and you may experience performance issues. – Fernando Contreras Aguilar Jul 22 '22 at 16:19
  • Correctly tested, thank you Fernando – faccio Jul 22 '22 at 16:36