поэтому я просто сделал нижнюю панель навигации. проблема в том, что моя нижняя панель навигации исчезла, когда я перешел на другую страницу, как будто вся страница была заменена.
Я искал любое руководство, в основном показывающее, как сделать нижнюю панель навигации, но не показывающее, пока у нас не появится кнопка внутри «корневых страниц навигации». (проверьте 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).
ты неправильно это реализуешь
попробуйте этот пример
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],
),
);
} }
Итак, я нашел проблему: это была ошибка навигационного маршрута. я конвертирую 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
},
),
),
);
}
}
попробуйте поместить кнопку для перехода к NextPage() внутри screen0, посмотрите, исчезла ли ваша нижняя навигация или нет, я не могу запустить ваш код, он устарел