Can I have two MaterialApp widgets in an app in Flutter - flutter

I have two questions with and "if" regarding the first question. As the title says I know it's better to have one MaterialApp in an App in Flutter and making Scaffold widgets for screens. But in a situation like this App which I followed for learning purposes and it's really written well and very clean. but it uses "TabBarView" as a default home for the entire app. So if I want to add another screen like "LoginSreen" that's not part of the "TabBarView" it's not inheriting the "MaterialApp" widget features. So I have to add a "MaterialApp" widget independently for that screen.
So the question is, is it ok to have two "MaterialApp" widgets in a situation like this?
if yes does it affect any variables that's shared among the screens like "SharedPreference"? or what does it affect?
If it's a bad behavior to have two "MaterialApp" widgets to in an App, Then how can you get rid of the "NavScreen()" and implement the TabBarView in the screens, Because I have tried many ways and looked at many of open source projects like this they have "TabBarView" widget as the body and start of the project.

yes you can definitely have two mat apps. but its not recommended.

Related

Optimize a GridView of data inside a pageview

I'm working on a custom calendar package but I'm having some performance difficulties while doing that.
My calendar layout is built from PageViews and each pageview contains a Gridview and each GridView contains 42 children representing the days of the month. Like this:-
Issue -
The problem is with scrolling the pageview. When I scroll to the new PageView the new PageView gets build and it builds its GridView and GridView builds its Children. All these tasks while scrolling leads to jank in scrolling animation.
Note: Scrolling to previous PageViews is smooth because I'm using AutomaticKeepAlives in PageView which stops PageView from rebuilding constantly on scroll.
DartPad -
The example DartPad for the above calendar can be found here - https://dartpad.dev/?id=762d835c5b9acadd785ee9269294c1e6
Now, what I'm looking for are the ways through which I can improve its performance.
Maybe I can somehow reuse the components for GridView children's dates by manually caching them by storing them as fields somewhere. But I don't know if that would work as these date styles have non-constant properties like the trailing one has different colors and the general one has a different one.
Maybe I can somehow preload pageviews in advance? I don't know if that would work when swiping fast.
Also, if it matters, currently I'm using Riverpod in my package for managing the calendar state.
So, if there is any way to improve the performance then please help me with that.
Current dirty solutions I found to this problem are:-
Setting viewportFraction: 0.99 in PageController of PageView. (It will help as it preloads the previous page and forward page). Suggested here #504337877.
Or use this preload_page_view package. Suggested here #636388237.
Currently, flutter doesn't support pre caching the PageView pages in advance but there are several issues about it on Github like this - #31191 , #45632 , and a closed pull request #42107 due to IOS related issue.
I failed to reuse the same widget in multiple places without rebuilding them.
And even if I succeed with the above I might fail to reuse states of child widgets of PageView as changing Pages means the whole child of PageView to be rebuilt as the index is new. So I cannot cache child widgets until I can reuse states in PageView.builder and GridView.Builder. A similar case for ListView is described in #49126.
If I'm wrong about the reusing same widget at multiple places then please correct me with a working small example as I'm more than happy to learn more. You can use this DartPad as starting point. The task is to bring the rebuild of customContainer from 42 to 1.
Not accepted as an answer as there could be more great answers to this in the future.

What is the best practice to improve performance?

I'm newly learning and creating simple app using flutter.
I created drawer inside Scaffold for some pages and I got confused if when I click the ListTiles, should it be routing the pages or just switch the body widget using setState().
I guess setState() must perform better but I'm not sure if this is a good practice for pages. If it does not have a big difference in performance, I would like to use routing the pages since it will be uniformed.
Personal opinion:
Avoid separating widgets into functions, use StatelessWidget instead. Cause every render function will rebuild whatever parameter changes.
Avoid using setState as much as possible, especially for large Widgets, instead use provider, get or simply use ValueNotifier if you dont want library. Cause setState will mark all things to be rerender include widgets that not need to be rerender.
Do not render too many things at once, if possible only render the views that are / are about to be displayed. Example using ListView.builder instead of ListView, ... etc
With image, please resize to suit your needs, a 2000x2000 image loaded as a 24x24 icon is clearly not a good idea.
using const.
I'd suggest to redirect user to the next page as it won't require a StatefulWidget (you can use navigator to navigate user to another activity) which will be lighter to run, as if you use IndexedStack or dynamically assign the widget it'll require the StatefulWidget..

Is there a flutter widget for this type of choice bar?

This is taken from the ESPN website where you can select one of the 3 options within the choice bar and it shows the information related to your choice. Is there any flutter widget for this? Choice chips are the closest one I've found but they are not connected together. Just wondering if there is a widget for this before spend the time to build one myself.
You can try something like this. https://pub.dev/packages/toggle_bar
But, IMHO, your own implementation will be more flexible.
You can use the built-in TabBar widget.
Take a look at this article:
https://flutter.dev/docs/cookbook/design/tabs

When to use new Screens in Flutter instead of TabBarView

I am fairly new to Flutter and I try to understand when and why it would be necessary to navigate to a new screen. Most apps keep the same AppBar, Drawer & BottomNavigationBar (if any) through all the different "screens". Wouldn't it be easier to just have one single TabBarView, or only replace the Scaffold's body ?
I have a hard time to really understand the concept of why there needs to be a new Scaffold when routing. I couldn't find anything helpful in the official Flutter doc, even the Cookbook show you a Navigation example with 2 completely new screens just to show a different Text widget inside the Scaffold's body.
Also, what about the efficiency of always rebuilding the whole Scaffold ?
When you route to new page, the previous page stored in history of navigator, so you can easily return to previos page just clicking Back button. In principle all depends on what you need. You may use new page with its own Scaffold as well as one page with single Scaffold and different body widgets. For last case you need to controll Back button manually so this way is enough expensive in development.

In Flutter is there a way to have different navigation stacks

I come from react-native and I am used to using react navigation, which allows you to make different stacks each with different routes in them.
Flutter appears to work where you have to put all your routes in one file, is there no way to split them up?
My app has 3 main sections and each screen in a section would ideally share blocs, but I cant find a way to make each section independent of the other sections which means either all the screens must share all the blocs or none of them.
Maybe you want every screen in section possible have a Navigator of itself ?
Default Flutter using a Navigator in app and navigate with Navigator.of(...). An app can use more than one Navigator with Navigator Widget.
Nesting Navigators
Code sample