BottomNavigationBar without loading all pages at once

Viewed 666

I have a screen with a BottomNavigationBar and an IndexedStack that swaps the child view based on the bottom bar index.

Everything is ok, except that all four pages are created at once, loading their data that is quite heavy and slowing down the app for some seconds.

Is there a setup that allows me to load each page only when the corresponding tab gets tapped?

2 Answers

Condition1: You want to simply load all tabs under IndexStack() at once during start and preserve them. Solution: Use 'const' in front of all tabs in IndexedStack() > children[].

Condition 2: You want to load only the Homepage and the rest of the pages on their respective index clicks. Solution: In children[] under IndexdStack() provide ternary condition with option for empty containers for all tabs. Put ternary condition of currentIndex. In this case though, the respective tab will load each time you click on it.

Condition 3: You want to load only the Homepage and the rest of the pages on their respective index clicks and preserve them once loaded. Solution:

  1. Use the solution for condition 2
  2. Set up a bool 'ex. pageLoaded'. One for each tab.
  3. Call the bool in the IndexedStack() > OnTap. Make it true on respective index clicks.
  4. Set up another ternary operation against the first ternary operation with 'const Tabname' as the alternative.

I would suggest to remove the IndexedStack and make the widgets List and render the data based on the index.

List<Widget> _pages = [Home(), Business(),School()];

Make the Provider/Bloc instance on your bottom navigation container widget

return MultiProvider(
   providers [
     Provider<Something>(create: (_) => Something()),
   ],
   child :Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Sample'),
      ),
    body: _pages[_selectedIndex],
    bottomNavigationBar: BottomNavigationBar(
    items: const <BottomNavigationBarItem>[
      BottomNavigationBarItem(
        icon: Icon(Icons.home),
        label: 'Home',
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.business),
        label: 'Business',
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.school),
        label: 'School',
      ),
    ],
    currentIndex: _selectedIndex,
    selectedItemColor: Colors.amber[800],
    onTap: _onItemTapped,
  )
)

On each page bind the consumer of the provider, call the api in your provider

Related