How to show alert dialog box if page is switched in bottom navigation bar in flutter - flutter

Currently I am working on flutter project in which I have used bottom navigation bar and in one of the pages I have a form in which information needs to fill. In this case if the user switches to another page after filling information and does not submit it, I want to show dialog box to user that "You have information filled leaving this page will discard the info". Please help.
I have tried WillPopScope widget but it only works when you press back button I want to show dialog box when the text fields are filled but not submitted and without submitting user tries to switch to another page.

In the onTap callback, check if the Navbar Item index is not equal to the Item which contains the form. If it is different, show the dialog and await its response.
void _onItemTapped(int index) async {
if(_selectedIndex == formItemIndex && index != formItemIndex)
{
// await showDialog();
}
setState(() {
_selectedIndex = index;
});
}
BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
)

Related

How to Navigate to the next page after closing an interstitial ad in flutter

I want my ad to show every three clicks.
The first click should show an ad.
The next two clicks should not show any ad. and then the fourth should.
This process currently works fine, the only issue is that I want to navigate to the next page after the ad closes but currently, nothing happens when I close the ad. it just remains on the current page
So basically, the first click should show the ad and navigate to the next page when the interstitial ad is closed.
the second click should navigate alone.
the third click should navigate alone.
Then restart the process.
My code is below -
CategoryCardWithImage(
title: "networks",
image: "assets/images/networks.png",
press: () {
clickCount = clickCount + 1;
bool shouldDisplayAd =
clickCount == 1 || clickCount % 3 == 0;
if (shouldDisplayAd) return _showInterstitialAd();
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return NetworksPage();
}),
);
},
),
Help fix code
I use AlertDialog
to simulate what you would like to achieve.
You could add more if..else condition in the onPressed() function to know which page will be shown after selecting.
void router() {
var aaa = showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text('MyTitle'),
content: Text('sdf'),
actions: [
TextButton(
child: Text('ok'),
onPressed: () {
Navigator.pushNamed(context, creationCategory.id);
},),
],
));
}
return Scaffold(
appBar: AppBar(
title: const Text('Record'),
leading: null,
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add),
onPressed: (){
Navigator.pushNamed(context, creationCategory.id);
},
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () async {
router();
},
),
],
),
Fig1. Pushing that button to invoke void router()
Fig2. Popping Ad
Fig3. To close the Ad and then go to that specific pages.

How to land the user on a different page while using AutoTabsScaffold and BottomNavigationBar?

I'm using Auto_Route for routing in my application and AutoTabsScaffold makes it easier. But by default, the user is navigated to the first page in the bottom navigation bar but I want it to be navigated to third page by default. How can I do that?
Here's a snippet of the code:
AutoTabsScaffold(
routes: [
A(),
B(),
C(),
D(),
E(),
],
bottomNavigationBuilder: (_, tabsRouter) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.black,
selectedItemColor: const Color(0XFFEAF8FF),
unselectedItemColor: Colors.grey,
currentIndex: tabsRouter.activeIndex,
onTap: tabsRouter.setActiveIndex,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.groups_outlined), label: ""),
BottomNavigationBarItem(icon: Icon(Icons.search), label: ""),
BottomNavigationBarItem(
icon: Icon(Icons.catching_pokemon), label: ""),
BottomNavigationBarItem(
icon: Icon(Icons.library_add_check_outlined), label: ""),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline), label: ""),
],
);
I want the user to land on C() and not A(). How can I do that? Thanks in advance.
Had the same issue.
I use auto_route package in my project.
We can see that current index depend on tabsRouter.activeIndex property.
So, I just added to the preferred route initial: true, property.
Like this:
CustomRoute(
path: '/',
page: MainScreen,
name: 'MainScreenRoute',
guards: [AuthGuard],
transitionsBuilder: TransitionsBuilders.fadeIn,
children: [
AutoRoute(
path: 'wallet',
page: WalletScreen,
),
AutoRoute(
path: 'trades',
page: TradesScreen,
),
AutoRoute(
path: 'market',
initial: true,
page: MarketScreen,
),

Flutter app - Problems Lifting State...Suggestions?

I'm working on a Flutter app and trying to make my bottom navigator bar more universal. As part of that, I've moved it to its own file and now need to simply lift state up to the parent class in order to highlight the selected icon. I call it like so from the parent:
bottomNavigationBar: buildBottomNavBar(
selectedIndex: selectedIndex,
redrawDisplay: redrawDisplay,
context: context,
),
And the bottomNaviBar is built like so:
return BottomNavigationBar(
currentIndex: selectedIndex,
onTap: (int index) {
selectedIndex = index;
redrawDisplay(selectedIndex);
onBottomMenuTap(index, appProject.picsSelectable, context);
},
elevation: 5.0,
iconSize: 30.0,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.note_add),
label: 'Add Metadata',
),
BottomNavigationBarItem(
icon: Icon(Icons.share),
label: 'Share Pics',
),
BottomNavigationBarItem(
icon: Icon(Icons.delete),
label: 'Delete Pics',
),
],
);
The 'redrawDisplay' function is simply a function in the parent class that sets state, like so:
void redrawDisplay({int selectedIndex}) {
setState(() {
this.selectedIndex = selectedIndex ?? 0;
});
}
I swear this was working a few days ago, but now I'm getting the following exception:
════════ Exception caught by gesture ═════════════════════════════════════════════
Closure call with mismatched arguments: function '_SearchScreenState.redrawDisplay'
Receiver: Closure: ({int selectedIndex}) => dynamic from Function 'redrawDisplay':.
Tried calling: _SearchScreenState.redrawDisplay(0)
Found: _SearchScreenState.redrawDisplay({int selectedIndex}) => dynamic
═══════════════════════════════════════════════════════════════════════
Obviously something has changed in my code, but I have been staring at this for hours and haven't cracked it yet. Anybody have some insight into what I've screwed up?
Thanks in advance.

bottom navigation bar not switching tabs in flutter

I want to use fancy bottom navigation in flutter. When i switch between tabs, it is showing the tab switching only at the navigation bar but, The body is not switching. It is not showing another tabs as i switch.
Here's my code
return Scaffold(
body: _getPage(currentPage),
bottomNavigationBar: FancyBottomNavigation(
key: bottomNavigationKey,
tabs: [
TabData(iconData: Icons.home,title: 'Home'),
TabData(iconData: Icons.search, title: 'Search'),
TabData(iconData: Icons.person, title: 'Profile'),
],
onTabChangedListener: (position){
setState(() {
currentPage = position;
final FancyBottomNavigationState fState =
bottomNavigationKey.currentState;
fState.setPage(position);
print('currentPage = $currentPage');
});
},
)
);
_getPage(int page){
switch(page) {
case 0:
return Page1();
case 1:
return Search();
case 2:
return Profile();
}
}
You don't need the GlobalKey here. It is enough to just set the currentPage value in the setState.
The Dev Nathan Withers writes here that the key prop defaults to null and is only used for Programmatic Selection of tabs. This special use case is only relevant if you want to change tabs by not clicking on the actual buttons. You don't need this feature. You can check out the example at line 48 to 50 for an actual use-case for the key prop.
Also examine if an IndexedStack suits you. It saves the pages state. You're _getPage() method destroys and builds each page new on each switch.
I put everything together in this example:
class _HomePageState extends State<HomePage> {
int _currentPage = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
top: false,
child: IndexedStack(
index: _currentPage,
children: [StartView(), AllServicesView()],
),
),
bottomNavigationBar: FancyBottomNavigation(
tabs: [
TabData(iconData: Icons.home,title: 'Home'),
TabData(iconData: Icons.search, title: 'Search'),
],
onTabChangedListener: (position){
setState(() {
_currentPage = position;
print('currentPage = $_currentPage');
});
},
)
);
}

How to Navigate to parent of widget in flutter

I want to navigate to the second bottom item on a page in flutter, from other pages.
The parent here is BottomNavigationBar that I want to configure to change the page (I define a key for it in Provider to access it from other pages).
List<Widget> pages = new List<Widget>();
BottomNavigationBar bottomNavigationBar;
updateList(){
pages.addAll({
Dashboard(),
AllServices(),
Account(),
Charge(),
});
}
int _selectedIndex = 0;
Widget _bottomNavigationBar(int selectedIndex,key) {
return BottomNavigationBar(
key: key,
onTap: (int index) => setState(() => _selectedIndex = index),
currentIndex: selectedIndex,
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text("A page"),
),
BottomNavigationBarItem(
icon: new Icon(Icons.location_on),
title: new Text("B page")
),
BottomNavigationBarItem(
icon: new Icon(Icons.store),
title: new Text("C page")
),
BottomNavigationBarItem(
icon: new Icon(Icons.person),
title:new Text("D page")
),
],
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
updateList();
}
#override
Widget build(BuildContext context) {
final globalKeyForBottomNavigate = Provider.of<Controller>(context, listen: false).bottomNavigate;
return Scaffold(
bottomNavigationBar: _bottomNavigationBar(_selectedIndex,globalKeyForBottomNavigate),
body: pages[_selectedIndex],
);
}
And children are Page A, B, C, D. now from page A I Navigate to Page F. Then if an action is triggered, I want to navigate to page B, but my solution is to change the index of BottomNavigationBar in page F and then navigate to page A. It works, but does not directly navigate to the content of page B and the BottomNavigationBar. In my solution, I say ok first change index of BottomNavigationBar, then go to last page (that here is Page A), but as you see, I do not know how to directly navigate to page B. This is the code for page F.
onTap: (){
var bottomKey=Provider.of<Controller>(context, listen: false).bottomNavigate;
final BottomNavigationBar navigationBar = bottomKey.currentWidget;
navigationBar.onTap(1);
Navigator.pop(context);
},
You can try using an environment variable in the app. and based on the action change the value of environment variable. Secondly bind the value of selectedIndex with that environment variable, so whenever that variable change, it will change the value of selectedIndex and call the dashboard page again with new value of the index it will navigate you to the required page from the bottom bar.