How to determine if a Widget is Stateful or Stateless in Flutter? - flutter

I understand the basics here. If my data is going to change it should be stateful so I can update it otherwise stateless.
My question is more oriented in a bottomnavigation scenario. So, I have 3 tabs in my bottomnavigator (Profile, Home, Settings). The entry point is Home which is a stateful Widget.
The other two Widgets I want to basically populate the information in them with the api data.
The Problem
If I am in the Home screen and I click in the Profile icon in the bottomnavigator it does not load the information from the api. Even if it does, If I click in the Home screen and click again in the Profile screen to go back, the information does not refresh.
Solution
So what would be the way to handle this? I expect that if I click in each of the bottomnavigation items the information is refreshed with the api data. Is this because the Widgets are Stateful or Stateless or I am missing something else?

By default, the pages in Bottom Navigation bar refreshes/rebuild when they are are tapped on.
Make sure a few things in your app-
You are not using a "indexed stack" or any similar widget for these pages. These widgets preserves the state of your page
The navigation is taking place on its own. You have not defined any Navigator.Push etc for tap's in navigation bar.
You should call the API inside the initState method of that particular page. Like if you need profile details, call the api for profile information inside the initState method of Profile Tab and not the "Scaffold" page which has the navigation bar.

Related

ShowSearch function rebuilds the whole widget tree on Flutter

I have a problem when i navigate to multiple pages and then show search.
More specifically, i have a product page with some details. At the bottom there is a list of similar products.
The flow is:
open many similar products (so I navigate to the same screen using Navigator pushNamed).
then, navigate from the las product page to the search page
tap on search bar, open search delegate using the showSearch function
My issue is that when i tap on the search bar, then the whole widget tree is rebuilded and my app is very heavy because rebuilds the previous product pages and everything else.
This happens due to the general rebuild on keyboard changes(i.e: showing and hiding Keyboard).
I recommend to have a heavy operation like loading data from backend should be held on initState in State with StatefullWidget.
Try to debug and understand why do you rebuild the tree. It seems to me, that you need to simplify a navigation flow.

How do you create a side navigation drawer that persists across pages?

I've looked through many tutorials for the side nav drawer. I can create one that works fine to lead to different pages. However, when I travel to a page that's different from home, it only gives me the arrow icon to go back to home at the top left instead of keeping the button to bring me back to the side navbar. How can I prevent this?
I can't use the home page to navigate everywhere because it's just supposed to be a blank splash screen.
You can define your drawer in a separate widget file, that you can import everywhere you have a scafold.
I created a package for it because I was missing similar functionality. If you want a Flutter approach for this navigation check out: https://api.flutter.dev/flutter/material/NavigationRail-class.html
Or if you want to have a look at my package: https://pub.dev/packages/side_navigation
It's because you're moving to a new page/Scaffold (probably using Navigator.push()). So, the default button in the AppBar will be the back button.
You can either have the same Drawer in every Scaffold you navigate to, which is not recommended since you'll just keep pushing routes to the navigation stack.
Or, you can change pages within the Scaffold. Check the interactive examples in BottomNavigationBar and NavigationRail to get an idea of how to do it. Basically instead of calling Navigator.push() when a tile in Drawer is tapped, just update the selected index and call setState().

Using bottom navigation with individual Navigators but single AppBar

I am trying to create an app that has the following basic setup for navigation:
tab1 -> subpage
tab2
tab3
with a bottom navigation bar for switching between the tabs and each tab having its own navigation stack. Furthermore I would like to add an AppBar with a drawer (as endDrawer) and the back button as leading widget in the AppBar.
The AppBar should be centrally managed so I put it in the main page of the app for maintenance purposes instead of having it on every page that is pushed. The drawer should also be updated later on when the user is logging in or out so it encouraged me more to place the AppBar only in the main page.
Now the issue is that I would like to update the AppBar to contain the back button when the app navigated to the subpage of tab1. Since the AppBar is in the parent I thought of RouteObservers as a possible solution by registering a RouteObserver on each NavigationState.
Yet I cannot get it to work because when I would like to subscribe on the RouteObserver in the HomePage in the didChangeDependencies() the currentState of the NavigatorState does not exist. Also I tried subscribing in the build method after the Scaffold with a flag for subscribing only once, but this didn't work either.
I created a github project with the basics of my current implementation:
https://github.com/S-Braeutigam/bottom-navbar-single-appbar
To get to the current state of code I used the following links:
https://codewithandrea.com/articles/multiple-navigators-bottom-navigation-bar/
https://api.flutter.dev/flutter/widgets/RouteObserver-class.html
Flutter 2.0 appbar back button disappeared if contains endDrawer (The solution gets close to what I would like to implement, but the AppBar should always be visible, not only on the sub page)
My main questions are:
Are RouteObservers the correct approach on how to track the navigation to subpages of tabs and display the back button based on it?
At what lifecycle hook in the main page should or could the subscription on the currentState of each NavigatorState be done? Wasn't able to find any where they are not null.

API data from provider seems to get lost during Navigation

I am a beginner level Flutter developer trying to resolve the issue with the Navigation stack.
In the existing app:
When user logs in to the app, login api call is shooted
Homescreen is rendered with Navigator.popUntill method
All the APIs in the providers get shooted and the respective tabs/screens get filled with api data.
Now, I want to include Onboarding screens before Homescreen, so I made below changes:
Navigator.push method used to include Onboarding screens.
After onboarding screens are over, user clicks on "To app" button
On click of "To app" button, the login call is made again
User is redirected to Homescreen with Navigator.popUntill method.
But now the data from providers is lost as the respective screens do not show any data. I am pretty sure that something is going wrong with the Navigation stack when I use Navigator.push method to add Onboarding screens but I do not have much expertise in Flutter to debug the issue. Need help with restoring the provider data when navigating to Onboarding screens.
I think that the cause isn't in a navigation stack. Probably you placed Provider widget lower than navigation (MaterialApp).
Try something like that or show your code for better understanding.
Provider(
create: (context) => ClassThatCallsAPI(),
child: MaterialApp(
// Navigator placed here and any route will
// get the same data from provider
// and also can put some

designing an app with multiple pages with different app bar and a single drawer

I am trying to build an app in Flutter in which I have multiple pages, each with their specific actions in the app bar. I would like to add a Drawer to the app which contains a list of page names that take them to the respective pages. I learnt that both AppBar and Drawer widgets have to be part of a Scaffold widget. Currently, all my pages are basically StatefulWidgets with the build method returning a complete Scaffold widget. If I want to include a Drawer, I think I will have to add the drawer object in each of my page. Is there a better way/pattern to do this?
Write the code for the drawer once and enclose it in a function. Then just call the function each time for that drawer.
eg)
drawer: myDrawer()
In one of my Apps, I have something similar. My Drawer is in the app class which is called in the main. This app class calls the home classes. My app class is also Stateful.
Each home class has his own Appbar and Search function.
The Drawer is called only in the app class.
Tell me if this explanation is okay for you or if you need a sample code.