Флаттерная нижняя навигация исчезает при нажатии на другую страницу с помощью кнопки

поэтому я просто сделал нижнюю панель навигации. проблема в том, что моя нижняя панель навигации исчезла, когда я перешел на другую страницу, как будто вся страница была заменена.

Я искал любое руководство, в основном показывающее, как сделать нижнюю панель навигации, но не показывающее, пока у нас не появится кнопка внутри «корневых страниц навигации». (проверьте home_page.dart)

или после посещения страниц нижней навигации мне не следует снова использовать Navigator.push?

я знаю, что есть пакет persist_bottom_nav_bar_v2, но это единственный способ?

Я также сделал другой проект с базовой панелью навигации, используя обычный setstate, но результат тот же. Есть ли что-то, что я пропустил, или использование пакета — единственный способ? Спасибо.

class MainWrapperController extends GetxController {
  final Rx<int> _selectedIndex = 0.obs;

  int get selectedIndex => _selectedIndex.value;

  void setSelectedIndex(int index) => _selectedIndex.value = index;

  List<NavigationItemModel> navItemModels = [
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Home",
      icon: Icons.home,
      page: const HomePage(),
    ),
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Report",
      icon: Icons.equalizer,
      page: const ReportMenuPage(),
    ),
    NavigationItemModel(
      navigatorKey: GlobalKey<NavigatorState>(),
      title: "Profile",
      icon: Icons.person,
      page: const ProfilePage(),
    ),
  ];
}

main_wrapper.dart

class MainWrapper extends StatefulWidget {
  const MainWrapper({super.key});

  @override
  State<MainWrapper> createState() => _MainWrapperState();
}

class _MainWrapperState extends State<MainWrapper> {
  var mainWrapperController = Get.find<MainWrapperController>();

  @override
  Widget build(BuildContext context) {
    var navPages = mainWrapperController.navItemModels
        .map(
          (item) => Navigator(
            key: item.navigatorKey,
            onGenerateRoute: (setting) {
              return MaterialPageRoute(builder: (context) => item.page);
            },
          ),
        )
        .toList();

    var navItems = mainWrapperController.navItemModels
        .map((item) =>
            BottomNavigationBarItem(icon: Icon(item.icon), label: item.title))
        .toList();

    return PopScope(
      canPop: false,
      onPopInvoked: (state) {},
      child: Scaffold(
        body: Obx(
          () => IndexedStack(
            index: mainWrapperController.selectedIndex,
            children: navPages,
          ),
        ),
        bottomNavigationBar: Obx(
          () => BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedFontSize: 0,
            unselectedFontSize: 0,
            backgroundColor: Colors.white,
            selectedItemColor: ColorConstant.selectedIcon,
            showSelectedLabels: false,
            showUnselectedLabels: false,
            items: navItems,
            iconSize: 36,
            onTap: (index) => mainWrapperController.setSelectedIndex(index),
            currentIndex: mainWrapperController.selectedIndex,
          ),
        ),
      ),
    );
  }
}

home_page.dart

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: ColorConstant.background,
        body: Column(
          children: [
            // here when i push, the whole page is changed not persisting bottom navbar
            SimpleButtonWidget(
              onPressed: () => Get.to(const NextPage()),
              text: 'Click Me',
            )
          ],
        ));
  }
}

следующая_страница.dart

class NextPage extends StatelessWidget {
  const NextPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text("HELLO FROM NEXT PAGE");
  }
}

ожидая, что нижняя панель навигации не исчезнет при навигации изнутри «корневых страниц навигации» (см. home_page.dart).

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

ты неправильно это реализуешь

попробуйте этот пример

class Home extends StatefulWidget {

   @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int currentIndex = 0;

  @override
  Widget build(BuildContext context) {
return Scaffold(
    bottomNavigationBar: NavigationBarTheme(
      data: NavigationBarThemeData(
        labelTextStyle: MaterialStateProperty.resolveWith<TextStyle>(
          (Set<MaterialState> states) =>
              states.contains(MaterialState.selected)
                  ? const TextStyle(
                      color: Color(0xFFBA172F),
                    )
                  : const TextStyle(color: Colors.black),
        ),
      ),
      child: NavigationBar(
        height: 60,
        onDestinationSelected: (value) {
          setState(() {
            currentIndex = value;
          });
        },
        selectedIndex: currentIndex,
        indicatorColor: const Color.fromARGB(30, 255, 82, 82),
        destinations: [
          NavigationDestination(
            icon: Icon(
              Icons.home_outlined,
              color: currentIndex == 0 ? const Color(0xFFBA172F) : null,
            ),
            label: 'Home',
          ),
          NavigationDestination(
              icon: Icon(
                Icons.grid_view_outlined,
                color: currentIndex == 1 ? const Color(0xFFBA172F) : null,
              ),
              label: 'Categories'),
          NavigationDestination(
              icon: Icon(
                Icons.whatshot_outlined,
                color: currentIndex == 2 ? const Color(0xFFBA172F) : null,
              ),
              tooltip: 'Sizzling Hot Offers',
              label: 'Trending'),
          NavigationDestination(
              //show badge only when something is selected //here temporary some bool used.
              icon: isWideScreen(context)
                  ? Icon(
                      Icons.favorite,
                      color: currentIndex == 3
                          ? const Color(0xFFBA172F)
                          : null,
                    )
                  : Badge(
                      backgroundColor:
                          const Color.fromARGB(255, 238, 255, 55),
                      label: const Text(
                        ' 1 ',
                        style: TextStyle(
                            color: Color(0xFFBA172F),
                            fontWeight: FontWeight.bold),
                      ),
                      child: Icon(
                        Icons.favorite,
                        color: currentIndex == 3
                            ? const Color(0xFFBA172F)
                            : null,
                      ),
                    ),
              label: 'Favorites'),
          NavigationDestination(
            icon: Icon(
              Icons.person,
              color: currentIndex == 4 ? Colors.red : null,
            ),
            label: 'Account',
          ),
        ],
      ),
    ),
    body: <Widget>[
     const Screen0(),
      const Screen1(),
      const Screen2(),
      const Screen3(),
      const Screen4(),
    ][currentIndex],
  ),
);

} }

попробуйте поместить кнопку для перехода к NextPage() внутри screen0, посмотрите, исчезла ли ваша нижняя навигация или нет, я не могу запустить ваш код, он устарел

Enrico Roselino 07.06.2024 08:04
Ответ принят как подходящий

Итак, я нашел проблему: это была ошибка навигационного маршрута. я конвертирую onGenerateRoute в основной, используя go_router, и сохраняю getx в качестве управления состоянием.

обратите внимание, это нарушит навигацию с помощью Navigator и Get. По крайней мере, закусочная getx все еще работает таким образом.

пока вы управляете go_router прямо внутри ShellBranch Route, нижняя навигация будет сохраняться.

main.dart

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp.router(
      title: 'Flutter Demo',
      routeInformationProvider: goRouter.routeInformationProvider,
      routerDelegate: goRouter.routerDelegate,
      routeInformationParser: goRouter.routeInformationParser,
      backButtonDispatcher: goRouter.backButtonDispatcher,
      smartManagement: SmartManagement.full,
    );

    // return MaterialApp.router(
    //   title: 'Flutter Demo',
    //   routerConfig: goRouter,
    // );
  }
}

маршруты.dart

// final _rootNavigatorKey = GlobalKey<NavigatorState>();
// final _shellHomeKey = GlobalKey<NavigatorState>(debugLabel: 'home');
// final _shellProfileKey = GlobalKey<NavigatorState>(debugLabel: 'profile');

final _rootNavigatorKey = Get.key;
final _shellHomeKey = Get.nestedKey(1);
final _shellProfileKey = Get.nestedKey(2);

final goRouter = GoRouter(
  debugLogDiagnostics: true,
  navigatorKey: _rootNavigatorKey,
  initialLocation: "/login",
  routes: [
    // other route outside shell
    GoRoute(
      path: "/login",
      builder: (context, state) => const LoginPage(),
    ),

    // shell routes
    StatefulShellRoute.indexedStack(
      builder: (BuildContext context, GoRouterState state,
          StatefulNavigationShell navigationShell) {
        return BottomNavbarWidget(navigationShell);
      },
      branches: [
        StatefulShellBranch(
          navigatorKey: _shellHomeKey,
          routes: [
            GoRoute(
              path: "/home",
              pageBuilder: (BuildContext context, GoRouterState state) =>
                  MaterialPage(key: state.pageKey, child: const HomePage()),
              routes: [
                GoRoute(
                  path: "nested_home",
                  builder: (context, state) => const NestedHome(),
                )
              ],
            ),
          ],
        ),
        StatefulShellBranch(
          navigatorKey: _shellProfileKey,
          routes: [
            GoRoute(
              path: "/profile",
              pageBuilder: (BuildContext context, GoRouterState state) =>
                  MaterialPage(key: state.pageKey, child: const ProfilePage()),
              routes: [],
            ),
          ],
        )
      ],
    ),
  ],
  // errorBuilder: (context, state) => ErrorPage(state.error),
);

При переходе на экран домашней страницы вы будете перенаправлены на нижнюю панель навигации с ее корневым экраном.
логин_страница.dart

class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          style: const ButtonStyle(
            backgroundColor: WidgetStatePropertyAll(Colors.blue),
          ),
          child: const Text("Login"),
          onPressed: () {
            context.go("/home"); // can go
            //Get.toNamed("/home"); // crashed
            //Navigator.pushNamed(context, "/home"); // crashed
          },
        ),
      ),
    );
  }
}

Другие вопросы по теме