How to reload page on indexedstack in Flutter

Viewed 541

Currently i'm using indexedstack and bottomnavigationbar, there are two pages "HomePage" & "SearchPage". These two pages i put in a children inside indexedstack widget. Now the problem is

  1. If i switch to Search Page or switch back to Home Page it does not reload the page. How to solve this issue using the current widget which is indexedstack widget.
  2. Whenever i run the app it loads all the pages including Search page which is not a current page.

Below is the sample code.

main

void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: App(),
    );
  }
}
class App extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => AppState();
}
class AppState extends State<App> {
  static int currentTab = 0;
  final List<TabItem> tabs = [
    TabItem(
      tabName: "Home",
      icon: Icons.home_outlined,
      page: HomePage(),
    ),
    TabItem(
      tabName: "Search",
      icon: Icons.search,
      page: SearchPage(),
    ),
  ];
  AppState() {
    tabs.asMap().forEach((index, details) {
      details.setIndex(index);
    });
  }
  void _selectTab(int index) {
    if (index == currentTab) {
      tabs[index].key.currentState!.popUntil((route) => route.isFirst);
    } else {
      setState(() => currentTab = index);
    }
  }
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final isFirstRouteInCurrentTab =
            !await tabs[currentTab].key.currentState!.maybePop();
        if (isFirstRouteInCurrentTab) {
          if (currentTab != 0) {
            _selectTab(0);
            return false;
          }
        }
        return isFirstRouteInCurrentTab;
      },
      child: Scaffold(
        body: IndexedStack(
          index: currentTab,
          children: tabs.map((e) => e.page).toList(),
        ),
        bottomNavigationBar: BottomNavigation(
          onSelectTab: _selectTab,
          tabs: tabs,
        ),
      ),
    );
  }
}

TabItem

class TabItem {
  final String tabName;
  final IconData icon;
  final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
  int _index = 0;
  late Widget _page;
  TabItem({
    required this.tabName,
    required this.icon,
    required Widget page,
  }) {
    _page = page;
  }
  void setIndex(int i) {
    _index = i;
  }
  int getIndex() => _index;
  Widget get page {
    return Visibility(
      visible: _index == AppState.currentTab,
      maintainState: true,
      child: Navigator(
        key: key,
        onGenerateRoute: (routeSettings) {
          return MaterialPageRoute(
            builder: (_) => _page,
          );
        },
      ),
    );
  }
}

BottomNavigation

class BottomNavigation extends StatelessWidget {
  BottomNavigation({
    required this.onSelectTab,
    required this.tabs,
  });
  final ValueChanged<int> onSelectTab;
  final List<TabItem> tabs;
  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      items: tabs
          .map(
            (e) => _buildItem(
              index: e.getIndex(),
              icon: e.icon,
              tabName: e.tabName,
            ),
          )
          .toList(),
      onTap: (index) => onSelectTab(
        index,
      ),
    );
  }
  BottomNavigationBarItem _buildItem(
      {required int index, required IconData icon, required String tabName}) {
    return BottomNavigationBarItem(
      icon: Icon(
        icon,
        color: _tabColor(index: index),
      ),
      title: Text(
        tabName,
        style: TextStyle(
          color: _tabColor(index: index),
          fontSize: 12,
        ),
      ),
    );
  }
  Color _tabColor({required int index}) {
    return AppState.currentTab == index
        ? Colors.red
        : Colors.black;
  }
}
0 Answers
Related