Home > OS >  Why FutureBuilder re-build every time?
Why FutureBuilder re-build every time?

Time:07-23

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],
    );
  }

 
}

CodePudding user response:

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

  • Related