[英]Flutter: ArrayIndexOutOfBoundsException with BottomNavigationBar
[英]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;
}
}
這是我的 appPage 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()],
),
]
}
這是我的根 controller:
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
方法中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.