In my Flutter app, I have a tabbar. Each tap is its own widget with lots of descendants widgets (see diagram).
In the Scaffold building the tabbar, the children are located in a IndexedStack widget - this is super cool, since it allows the user to change tabs without losing state.
Problem: Since we use IndexedStack, the entire widget tree for inactive (i.e in background) tabs are preserved, and all animations/servercalls are executed regardless.
Question: Is it possible to pause a widget + all the widgets descendants?
Expected result: Widgets gets paused/unpaused if they are in foreground or background, preserving resources but still not losing state.
Example:
Scaffold(
body: IndexedStack(index: i, children: [TabA(), TabB(), TabC()], // <- How to pause/unpause TabA, TabB, TabC?
bottomNavigationBar: // Tabbar widget here
)
Related
My app has a screen that is composed of several buttons and text labels which are conditionally visible based on the selection of the buttons (for example, a yes/no radio button asking whether you were exposed to a covid-positive individual, which would cause another radio button asking whether the encounter lasted more than 15 minutes to be displayed).
I know that stateless widgets for screens are preferable due to their improved performance, so I am trying to keep the screen widget stateless
The radio buttons in the example are actually custom statefull widgets wrapping a ToggleButton, so I would have the condition (controlling the visibility of widget) to flow between the main stateless widget and the statefull child widgets (with the toggle buttons)
I'm developing an app in flutter, and i got stuck while trying to preload a page in webview.
Basically, the app uses tabbar, with a few tabs with normal listview content in them, and 2 tabs that should have webview as content. Any idea how to preload the webviews and keep them alive in background while the app loads, so when the user swipes between tabs, and gets on the webview ones, the sites are already loaded and rendered so the UX is seamless. I have tried creating the WebView instance and assigning it to a variable using setstate on app load, but to no avail.
Any help would be appreciated.
So what you can try doing is this:
Wrap the widgets you are calling in your TabBar with a PageView like shown here.
You can also ensure that the WebView stays alive after loading once by extending your stateful widget with AutomaticKeepAliveClientMixin. While using this ensure that you declare:
bool get wantKeepAlive => true;
Edit:
In order to preload all your pages when your app launches you can use Indexed Stack in the class your TabBar is declared. Wrap the body and call all the pages there like this:
Widget build(BuildContext context) {
return
Scaffold(
body:IndexedStack(
index: _selectedIndex,
children: _children,
),),}
You can wrap your webview with the OffStage widget and set the offstage parameter to true. When some events are trigger and you're ready to show the page, flip the offstage parameter to false.
Can this animated widget replacement be done without page routes and a Stack with manual position resolving? A preview from a ListView should fly to the main position. I've done it with a Hero and Navigator.push(), but I want to do it on one screen with just setState((){index++;}) in a stateful widget.
I want the button to display on top of the GraphQL provider widget, and still be functional as it is going to be used for routing. I want both to run simultaneously(or as close as possible so it doesn't ruin the UI when loading).
I've tried running both of the widgets at the top but they do not run as I would like them to.
void main() {
runApp(LoginPage());
runApp(Login());
class LoginPage extends StatelessWidget
class Login extends StatelessWidget
I thought the output would be the Login widget layered on top of LoginPage but it was just the Login widget expanded without the LoginPage widget running in the background.
From the runApp documentation:
Calling runApp again will detach the previous root widget from the screen and attach the given widget in its place.
And:
If you wish to align your widget to one side of the screen (e.g., the top), consider using the Align widget. If you wish to center your widget, you can also use the Center widget
So, as #Nae said in the comments, you can use Stack for that. Like:
Stack(
children: <Widget>[
LoginPage(),
Login(),
]
)
Let's say I have a container on one side of the screen which I want to be present at all times even during navigation through different screens.
Is there any way by which I can achieve this? If yes, how?
This is an interesting question. I can give you a solution but don't know if its the correct way to do that.
In the MaterialApp widget there is a builder parameter which gives whole screen view as a parameter and can be wrapped up by another Widget. Here is an example.
MaterialApp(
....
builder: (context, widget) {
return Stack(
children: [
_myPersistantWidget(), // you can add your widget. May be inside Positioned widget?
widget //this is the whole screen that we are wrapping in the stack
],
);
},
....
);