getx
getx copied to clipboard
Cache results in example_nav2
There is a common use case for tabs to hold their state when switching among them. In the example_nav2, when selecting a product, it redirects to the product details, but then when visiting another tab and returning to the products tab, the product details are not longer visible.
https://user-images.githubusercontent.com/77690617/128570427-3d917996-38fb-43ed-b938-263b47dbfecf.mov
Is there a simple solution to this?
I'm considering specifying different GetDelegate
s for each tab and using Offstage
widgets to hide inactive tabs, but I imagine there is an easier way. And if the plugin were to solve the problem, how would you go about doing it?
@ahmednfwela do you have any thoughts on how this can be accomplished?
I kind of got it working by doing this:
https://user-images.githubusercontent.com/77690617/128708558-e15d0c7e-e7e5-441d-8808-0d0e9171345f.mov
class HomeController extends GetxController {
final RxInt tabIndex = 0.obs;
}
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return GetRouterOutlet.builder(
builder: (context, delegate, currentRoute) {
return Obx(() {
return Scaffold(
body: Stack(
children: [
Offstage(
offstage: controller.tabIndex() != 0,
child: GetRouterOutlet(
initialRoute: Routes.DASHBOARD,
anchorRoute: Routes.DASHBOARD,
key: Get.nestedKey(Routes.HOME),
),
),
Offstage(
offstage: controller.tabIndex() != 1,
child: GetRouterOutlet(
initialRoute: Routes.PROFILE,
anchorRoute: Routes.PROFILE,
key: Get.nestedKey(Routes.PROFILE),
),
),
Offstage(
offstage: controller.tabIndex() != 2,
child: GetRouterOutlet(
initialRoute: Routes.PRODUCTS,
anchorRoute: Routes.PRODUCTS,
key: Get.nestedKey(Routes.PRODUCTS),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: controller.tabIndex(),
onTap: (value) {
switch (value) {
case 0:
if (controller.tabIndex() == 0) {
delegate.backUntil(Routes.HOME);
} else {
controller.tabIndex.value = 0;
}
break;
case 1:
if (controller.tabIndex() == 1) {
delegate.backUntil(Routes.PROFILE);
} else {
controller.tabIndex.value = 1;
}
break;
case 2:
if (controller.tabIndex() == 2) {
delegate.backUntil(Routes.PRODUCTS);
} else {
controller.tabIndex.value = 2;
}
break;
default:
}
},
items: [
// _Paths.HOME + [Empty]
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
// _Paths.HOME + Routes.PROFILE
BottomNavigationBarItem(
icon: Icon(Icons.account_box_rounded),
label: 'Profile',
),
// _Paths.HOME + _Paths.PRODUCTS
BottomNavigationBarItem(
icon: Icon(Icons.account_box_rounded),
label: 'Products',
),
],
),
);
});
},
);
}
}
The primary issue is that the nav stack doesn't get updated when switching tabs (I'm still not sure how to update the history without forcing a reload, though I bet there is a way)
Do you see any glaring issues with this approach? Is this something worth baking into a GetBottomTabView
?
The other issue I'm observing is that navigating to a new route on one tab will reset all other tabs back to their anchorRoutes
Actually the solution is much simpler than this, change the onTap logic here https://github.com/jonataslaw/getx/blob/master/example_nav2/lib/app/modules/home/views/home_view.dart#L37 to this:
case 2:
final nearestEntryIndex = delegate.history.lastIndexWhere(
(entry) =>
entry.location?.startsWith(Routes.PRODUCTS) == true,
);
final nearestEntry = nearestEntryIndex >= 0
? delegate.history[nearestEntryIndex].location!
: Routes.PRODUCTS;
delegate.toNamed(nearestEntry);
break;
Hi, Any news about keeping states for bottom nav bar pages? Im also facing with same issue.
@ahmednfwela Is there any easy way?
Get.put<MyController>(MyController(), permanent: true);
permanent=true solved my problem.
I'm also using version 4.6.5 and have the same problem. It seems that this problem has always existed and has not been solved yet