首页 > 解决方案 > 如果我们在 GetX 上使用 bottomNavigationBar,如何使用内部导航

问题描述

我正在尝试body在小部件的内部进行导航bottomNavigationBar,这是我的代码:

class WrapperController extends GetxController {
  int currentIndex = 0;
  List<BottomNavigationElement> items = [];

  Widget navigationTab({GlobalKey<NavigatorState> naviKey, Widget widget}) {
    return Navigator(
      key: naviKey,
      onGenerateRoute: (routeSettings) {
        return GetPageRoute(page: () => widget);
      },
    );
  }

  Widget bottomNavigationBar() {
    return BottomNavigationBar(
      selectedItemColor: Get.theme.accentColor,
      type: BottomNavigationBarType.fixed,
      currentIndex: currentIndex,
      backgroundColor: Get.theme.primaryColor,
      onTap: (int index) => _selectTab(index),
      items: items.map((e) => e.bottomBarItem).toList(),
    );
  }

  void _selectTab(int index) {
    if (index == currentIndex) {
      items[index]
          .navigationKey
          .currentState
          .popUntil((route) => route.isFirst);
    } else {
      currentIndex = index;
    }
    update();
  }

  Future<bool> onWillPop() async {
    final isFirstRouteInCurrentTab =
        !await items[currentIndex].navigationKey.currentState.maybePop();
    if (isFirstRouteInCurrentTab) {
      if (currentIndex != 0) {
        // _selectTab(1);
        return false;
      }
    }
    return isFirstRouteInCurrentTab;
  }

  @override
  void onInit() {
    super.onInit();
    items = [
      //Каталог
      BottomNavigationElement(
        bottomBarItem: BottomNavigationBarItem(
          icon: Icon(Icons.search),
          label: "Home",
        ),
        bottomBarView: HomePage(),
        navigationKey: Get.nestedKey('0'),
      ),
      //Любимое
      BottomNavigationElement(
        bottomBarItem: BottomNavigationBarItem(
          icon: Icon(Icons.favorite_border),
          label: "Favorites",
        ),
        bottomBarView: FavoritesPage(),
        navigationKey: Get.nestedKey('1'),
      ),
      //Корзина
      BottomNavigationElement(
        bottomBarItem: BottomNavigationBarItem(
          icon: Icon(Icons.shopping_cart_outlined),
          label: "Cart",
        ),
        bottomBarView: CartPage(),
        navigationKey: Get.nestedKey('2'),
      ),
      //Заказы
      BottomNavigationElement(
        bottomBarItem: BottomNavigationBarItem(
          icon: Icon(Icons.history),
          label: "History",
        ),
        bottomBarView: HistoryPage(),
        navigationKey: Get.nestedKey('3'),
      ),
      //Меню
      BottomNavigationElement(
        bottomBarItem: BottomNavigationBarItem(
          icon: Icon(Icons.menu),
          label: "Menu",
        ),
        bottomBarView: MenuPage(),
        navigationKey: Get.nestedKey('4'),
      ),
    ];
  }
}

class BottomNavigationElement {
  Widget bottomBarView;
  BottomNavigationBarItem bottomBarItem;
  GlobalKey<NavigatorState> navigationKey;
  BottomNavigationElement({
    @required this.bottomBarView,
    @required this.bottomBarItem,
    @required GlobalKey<NavigatorState> navigationKey,
  });
}

这是Wrapper小部件:

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetBuilder<WrapperController>(builder: (controller) {
      return Scaffold(
        body: IndexedStack(
          index: controller.currentIndex,
          children: controller.items
              .map((e) => controller.navigationTab(
                    naviKey: e.navigationKey,
                    widget: e.bottomBarView,
                  ))
              .toList(),
        ),
        bottomNavigationBar: controller.bottomNavigationBar(),
      );
    });
  }
}

这是HomePage具有导航按钮的(“搜索”):

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => Navigator.of(context).push(
            MaterialPageRoute(
              builder: (context) => Detail(),
            ),
          ),
          child: Text("Detail"),
        ),
      ),
    );
  }
}

问题是,当我Navigator.of (context) Get.to ()改为使用时,导航完全完成,而不是在体内。我需要使用内部导航Get.to (),我该怎么做?

标签: flutterdartflutter-getx

解决方案


有一个快速的解决方案

  1. 为底部导航栏创建一个单独的导航器(如果您想将身份验证与主逻辑分开)。

  2. 代码是:

    Expanded(
                child: Navigator(
                key: Get.nestedKey(1),
                initialRoute: controller.pageName.value,
                onGenerateRoute: HomeRouter.generateRoute,
              )
    )
    
  3. 导航

    void gotoPage(String page, BuildContext context) {
        pageName.value = page;
        print("Request to go to ${pageName.value}");
        Get.keys[1]!.currentState!.pushNamed(page);
        //if you want to change the URL in browser as well
        html.window.history.pushState(null, "/", page);
      }
    

推荐阅读