PersistentBottomNavBar
PersistentBottomNavBar copied to clipboard
popAllScreensOnTapOfSelectedTab with PersistentTabView.custom
How can I reproduce the "popAllScreensOnTapOfSelectedTab" functionality if I have a PersistentTabView Custom? I want that by tapping the bottom menu item, all open screens are closed and go to the selected page. Is this possible?
+1
+1
Any solution for this?
I looked at the source code of the package and this might help:
In your code, inside the class equivalent to the _CustomWidgetExampleState
class in the example code of this package, add the following variables:
late List<BuildContext?> _contextList;
int? _previousIndex;
Then inside the initState
, add the following after defining _controller
:
_previousIndex = _controller.index;
_contextList = List<BuildContext?>.filled(5, null);
Then in the body
of Scaffold
, inside PersistentTabView.custom
, add selectedTabScreenContext
parameter with the following function:
selectedTabScreenContext: (screenContext) {
_contextList[_controller.index] = screenContext;
},
For the customWidget
parameter, inside CustomNavBar
, update onItemSelected
as follows:
onItemSelected: (index) {
if (_controller.index != _previousIndex) {
_previousIndex = _controller.index;
}
if (_previousIndex == index) {
popAllScreens();
}
setState(() {
_controller.index = index;
});
},
And finally define popAllScreens()
function as below:
void popAllScreens() {
if (_navBarsItems()[_controller.index]
.onSelectedTabPressWhenNoScreensPushed !=
null &&
!Navigator.of(_contextList[_controller.index]!).canPop()) {
_navBarsItems()[_controller.index]
.onSelectedTabPressWhenNoScreensPushed!();
}
if (Navigator.of(_contextList[_controller.index]!).canPop()) {
Navigator.of(_contextList[_controller.index]!).pop(context);
return;
}
}
This seemed to be working for me. Give it a try and let me know :)
@AkbarBakhshi this function works like charm -
void popAllScreens() {
if (_navBarsItems(context)[_controllers.index]
.onSelectedTabPressWhenNoScreensPushed !=
null &&
!Navigator.of(_contextList[_controllers.index]!).canPop()) {
_navBarsItems(context)[_controllers.index]
.onSelectedTabPressWhenNoScreensPushed!();
} else {
Navigator.popUntil(
_contextList[_controllers.index]!,
ModalRoute.withName(_navBarsItems(context)[_controllers.index]
.routeAndNavigatorSettings
.initialRoute ??
'/9f580fc5-c252-45d0-af25-9429992db112'));
}
}
May be this can help anyone. I just handle the pop upto 5 levels like this.
void popAllScreens() {
//TODO handle pop upto 5 levels
if (Navigator.of(contextList[controller.index]??context).canPop()) {
Navigator.of(contextList[controller.index]!).pop(context);
if (Navigator.of(contextList[controller.index]??context).canPop()) {
Navigator.of(contextList[controller.index]!).pop(context);
if (Navigator.of(contextList[controller.index]??context).canPop()) {
Navigator.of(contextList[controller.index]!).pop(context);
if (Navigator.of(contextList[controller.index]??context).canPop()) {
Navigator.of(contextList[controller.index]!).pop(context);
if (Navigator.of(contextList[controller.index]??context).canPop()) {
Navigator.of(contextList[controller.index]!).pop(context);
}
}
}
}
return;
}
}
_navBarsItems(context)[_controllers.index] .routeAndNavigatorSettings .initialRoute
This function is causing issue after some time. Like first time it works perfectly but when we start testing it again with nested secreen it will not work
@umair-ilyas had the same issue, this one seems to fix it for me:
selectedTabScreenContext: (screenContext) { if (_contextList[_controller.index] == null) { _contextList[_controller.index] = screenContext; } }
This should be added as an argument to PersistentTabViewCustom.custom
.