GetMidleware 无法在 bottomNavigationBar 上工作 - 抖动 - GetX
GetMidleware not working on bottomNavigationBar - flutter - GetX
我对 GetMidleware
有疑问,所以我在 bottomNavigationBar
中有 3 个项目:
- 主页
- 我的票
- 简介
我希望用户可以在不登录的情况下访问主页,所以我将中间件放在 myTicket
和 Profile
上,但是当我单击 MyTicket 或 Profile 时,我仍然可以访问它而不是重定向到登录页面。
这是我的中间件 class :
class AuthMiddleware extends GetMiddleware {
final authService = Get.find<AuthService>();
@override
RouteSettings? redirect(String? route) {
if (!authService.currentUser.value.isAuthenticated) {
Get.log(authService.currentUser.value.isAuthenticated.toString());
return const RouteSettings(name: Routes.LOGIN);
}
return null;
}
}
这是我的应用程序页面class :
class AppPages {
static const INITIAL = Routes.ROOT;
static final routes = [
GetPage(
name: _Paths.ROOT,
page: () => const RootView(),
binding: RootBinding(),
),
GetPage(
name: _Paths.HOME,
page: () => const HomeView(),
binding: RootBinding(),
),
GetPage(
name: _Paths.MYTICKET,
page: () => const MyTicketView(),
binding: RootBinding(),
middlewares: [AuthMiddleware()],
),
GetPage(
name: _Paths.PROFILE,
page: () => const ProfileEditView(),
binding: RootBinding(),
middlewares: [AuthMiddleware()],
),
]
}
这是我的根控制器:
class RootController extends GetxController {
final Rx<String> title = Strings.home.obs;
final Rx<int> currentIndex = 0.obs;
final authService = Get.find<AuthService>();
@override
void onClose() {
super.dispose();
}
List<Widget> pages = [
const HomeView(),
const MyTicketView(),
const ProfileView(),
// const BlankView(),
];
//get current page for view
Widget get currentPage => pages[currentIndex.value];
//change page when bottom nav item is taped
Future<void> changePage(int _index) async {
changeTitle(_index);
if (Get.currentRoute == Routes.ROOT) {
await changePageInRoot(_index);
} else {
await changePageOutRoot(_index);
}
}
Future changeTitle(int index) async {
switch (index) {
case 0:
title.value = Strings.home;
break;
case 1:
title.value = Strings.myTicket;
break;
case 2:
title.value = Strings.myProfile;
break;
default:
}
}
//change page if previously page in root
Future<void> changePageInRoot(int _index) async {
currentIndex.value = _index;
await refreshPage(_index);
}
//change page if previously page out of root
Future<void> changePageOutRoot(int _index) async {
currentIndex.value = _index;
await refreshPage(_index);
await Get.offNamedUntil(Routes.ROOT, (Route route) {
if (route.settings.name == Routes.ROOT) {
return true;
}
return false;
}, arguments: _index);
}
}
//call page by index
Future<void> refreshPage(int _index) async {
switch (_index) {
case 0:
{
Get.find<HomeController>().onInit();
break;
}
case 1:
{
Get.find<MyTicketController>().onInit();
break;
}
case 2:
{
Get.find<ProfileController>().onInit();
// Get.find<BlankController>().onInit();
break;
}
}
}
这是我的根视图,我将 bottomNavigationBar
:
class RootView extends GetView<RootController> {
const RootView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(
() => Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(Dimensions.appBarHeight),
child: BackWidget(title: controller.title.value),
),
backgroundColor: Colors.white,
bottomNavigationBar: Material(
elevation: 10,
// borderRadius: BorderRadius.circular(20),
child: BottomNavigationBar(
selectedIconTheme:
const IconThemeData(color: CustomColor.primaryColor),
selectedLabelStyle: const TextStyle(fontSize: 15),
selectedItemColor: CustomColor.primaryColor,
backgroundColor: Colors.white,
elevation: 25,
type: BottomNavigationBarType.fixed,
currentIndex: controller.currentIndex.value,
onTap: (index) => controller.changePage(index),
items: [
bottomNavigationBarItemWidget(
'assets/svg/home.svg',
Strings.home,
),
bottomNavigationBarItemWidget(
'assets/svg/document.svg',
Strings.myTicket,
),
bottomNavigationBarItemWidget(
'assets/svg/profile.svg',
Strings.myProfile,
),
]),
),
body: controller.currentPage,
),
);
}
bottomNavigationBarItemWidget(String icon, String label) {
return BottomNavigationBarItem(
icon: SvgPicture.asset(
icon,
color: Colors.grey,
height: 24,
width: 24,
),
activeIcon: SvgPicture.asset(
icon,
color: CustomColor.primaryColor,
height: 24,
width: 24,
),
label: label,
tooltip: label,
);
}
}
BottomNavigationBar(也称为 TabBar)不改变路线。它本质上是单页的。因此,路由中间件不能毫无困难地与它们一起使用。
相反,您可以在导航栏项目视图的相应控制器上使用身份验证检查。一个很好的地方是在GetxController
的onReady
方法中。
我对 GetMidleware
有疑问,所以我在 bottomNavigationBar
中有 3 个项目:
- 主页
- 我的票
- 简介
我希望用户可以在不登录的情况下访问主页,所以我将中间件放在 myTicket
和 Profile
上,但是当我单击 MyTicket 或 Profile 时,我仍然可以访问它而不是重定向到登录页面。
这是我的中间件 class :
class AuthMiddleware extends GetMiddleware {
final authService = Get.find<AuthService>();
@override
RouteSettings? redirect(String? route) {
if (!authService.currentUser.value.isAuthenticated) {
Get.log(authService.currentUser.value.isAuthenticated.toString());
return const RouteSettings(name: Routes.LOGIN);
}
return null;
}
}
这是我的应用程序页面class :
class AppPages {
static const INITIAL = Routes.ROOT;
static final routes = [
GetPage(
name: _Paths.ROOT,
page: () => const RootView(),
binding: RootBinding(),
),
GetPage(
name: _Paths.HOME,
page: () => const HomeView(),
binding: RootBinding(),
),
GetPage(
name: _Paths.MYTICKET,
page: () => const MyTicketView(),
binding: RootBinding(),
middlewares: [AuthMiddleware()],
),
GetPage(
name: _Paths.PROFILE,
page: () => const ProfileEditView(),
binding: RootBinding(),
middlewares: [AuthMiddleware()],
),
]
}
这是我的根控制器:
class RootController extends GetxController {
final Rx<String> title = Strings.home.obs;
final Rx<int> currentIndex = 0.obs;
final authService = Get.find<AuthService>();
@override
void onClose() {
super.dispose();
}
List<Widget> pages = [
const HomeView(),
const MyTicketView(),
const ProfileView(),
// const BlankView(),
];
//get current page for view
Widget get currentPage => pages[currentIndex.value];
//change page when bottom nav item is taped
Future<void> changePage(int _index) async {
changeTitle(_index);
if (Get.currentRoute == Routes.ROOT) {
await changePageInRoot(_index);
} else {
await changePageOutRoot(_index);
}
}
Future changeTitle(int index) async {
switch (index) {
case 0:
title.value = Strings.home;
break;
case 1:
title.value = Strings.myTicket;
break;
case 2:
title.value = Strings.myProfile;
break;
default:
}
}
//change page if previously page in root
Future<void> changePageInRoot(int _index) async {
currentIndex.value = _index;
await refreshPage(_index);
}
//change page if previously page out of root
Future<void> changePageOutRoot(int _index) async {
currentIndex.value = _index;
await refreshPage(_index);
await Get.offNamedUntil(Routes.ROOT, (Route route) {
if (route.settings.name == Routes.ROOT) {
return true;
}
return false;
}, arguments: _index);
}
}
//call page by index
Future<void> refreshPage(int _index) async {
switch (_index) {
case 0:
{
Get.find<HomeController>().onInit();
break;
}
case 1:
{
Get.find<MyTicketController>().onInit();
break;
}
case 2:
{
Get.find<ProfileController>().onInit();
// Get.find<BlankController>().onInit();
break;
}
}
}
这是我的根视图,我将 bottomNavigationBar
:
class RootView extends GetView<RootController> {
const RootView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(
() => Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(Dimensions.appBarHeight),
child: BackWidget(title: controller.title.value),
),
backgroundColor: Colors.white,
bottomNavigationBar: Material(
elevation: 10,
// borderRadius: BorderRadius.circular(20),
child: BottomNavigationBar(
selectedIconTheme:
const IconThemeData(color: CustomColor.primaryColor),
selectedLabelStyle: const TextStyle(fontSize: 15),
selectedItemColor: CustomColor.primaryColor,
backgroundColor: Colors.white,
elevation: 25,
type: BottomNavigationBarType.fixed,
currentIndex: controller.currentIndex.value,
onTap: (index) => controller.changePage(index),
items: [
bottomNavigationBarItemWidget(
'assets/svg/home.svg',
Strings.home,
),
bottomNavigationBarItemWidget(
'assets/svg/document.svg',
Strings.myTicket,
),
bottomNavigationBarItemWidget(
'assets/svg/profile.svg',
Strings.myProfile,
),
]),
),
body: controller.currentPage,
),
);
}
bottomNavigationBarItemWidget(String icon, String label) {
return BottomNavigationBarItem(
icon: SvgPicture.asset(
icon,
color: Colors.grey,
height: 24,
width: 24,
),
activeIcon: SvgPicture.asset(
icon,
color: CustomColor.primaryColor,
height: 24,
width: 24,
),
label: label,
tooltip: label,
);
}
}
BottomNavigationBar(也称为 TabBar)不改变路线。它本质上是单页的。因此,路由中间件不能毫无困难地与它们一起使用。
相反,您可以在导航栏项目视图的相应控制器上使用身份验证检查。一个很好的地方是在GetxController
的onReady
方法中。