Flutter TabBar: Update tab (stateful widget) everytime a tab gets visible - flutter

happy new year! :)
I have three tabs, each holding a stateful widget. The data presented in tab #2 could be changed by the user within tab #3. Thus, when moving back from tab #3 to tab #2, I need to call an update() method within tab #2. Is there a stateful widget method that gets fired everytime the widget gets visible? If not, what opporutinites do I have in order to achieve this?
Best, Nico

The reason it's not updating is due to the widget already been rendered and now cached until the user exits the app. You can try numerous methods to make this work. For example, VoidCallBack method, adding an async function or leaving a blank setState in the initState itself. At the end of the day, it depends on how your app works. If you have a custom tabbar I'd recommend using the VoidCallBack method or maybe adding an async function which will be called before you return a render. Regardless these methods should work.

Related

Is there a way to inject a widget UNDER the Navigator with GoRouter?

In the MaterialApp constructor, I am injecting a widget in the builder method to handle push notifications. To process foreground notification, I would like to use this widget to show a notification bar (using another_flushbar) but I need a Navigator in the context for that, and MaterialApp's builder injects above the Navigator, so when I try to using it to push my notification bar, there is no Navigator accessible via the context.
Of course, I could wrap every screen of my app with my notification-handling widget, but it defeats the purpose. I want a widget that is always on screen when the app is running, and that can show my notification bar, wherever I am in my app.
Any idea how I can do that?
Here is how I solved it, while still using MaterialApp's builder to inject my NotificationHandler widget ABOVE the Navigator.
My NotificationHandler widget accepts a GlobalKey<NavigatorState> navigatorKey property
When I initialize my NotificationHandler widget inside of MaterialApp's builder, I pass it GoRouter.routerDelegate.navigatorKey
Inside of NotificationHandler, when I need a context with a Navigator above it, I use navigatorKey.currentContext insted of my local widget context.
This solution was inspired by this issue.

Handling Android's native back button on flutter_split_view

I'm currently developing an app which uses the flutter_split_view plugin to automatically display split view. There's one main annoyance, though, pressing the Android's native back button from the child screen (i.e. the right widget) simply closes the app.
I have tried using WillPopScope to call SplitView.of(context) on the child screen, because the SplitView constructor does not accept external controllers (e.g. TabController for tabs) which I could call to redirect the back button calls to the SplitView instead.
import 'package:flutter/material.dart';
import 'package:flutter_split_view/flutter_split_view.dart';
class ChildPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
SplitViewState splitView = SplitView.of(context);
return WillPopScope(
onWillPop: () async {
splitView.pop();
return false;
},
child: Scaffold(...),
);
}
}
Is there a way to solve this?
You can use the WillPopScope widget to capture the back button press event, and then use the splitView.pop() method to navigate to the previous screen, instead of closing the app.
By wrapping the Scaffold widget with a WillPopScope widget, you can intercept the back button press event, and then use the splitView.pop() method to navigate to the previous screen. The onWillPop callback should return Future, returning false will prevent the back button from doing its default action, in this case close the app. And that way you can redirect the back button calls to the SplitView instead.
This should work as expected if implemented correctly. However, you should test it on the actual device to make sure the behavior is the one you expect.
Don't think that split_view can help you split the current page into several single running StateFullWidget's. All the pages you see are only controlled by the context of the current page. So, the pop you reference in the subclassed widget will only apply to the current page. If the current page is the last page, there will be no page after running pop, so the program exits

In Flutter is there a way to check if the visible page has been presented modally

This is a common problem with iOS and is easily solved as all UIViewControllers have the property to check how they have been presented; whether modally or by being pushed onto a stack.
In Flutter we don't have view controllers, so we push new routes and one of the options is to use a fullScreenDialog. Your app bar will then have a close button and automatically pop when tapped.
But, if you want to dynamically adjust your Scaffold widgets based on whether they are presented in this way or not, there doesn't seem to be a way to detect that you are in a fullScreenDialog state (or modal). I have some pages that are part of the root tab navigation and therefore show a tab bar to switch between sections. I would like to reuse some of these pages but present them modally. In this case I want to remove the tab bar.
Is there any way to detect if a Navigator or Scaffold has been presented modally? Or do I just have to pass in a isModal bool?
I was thinking of perhaps a different solution based on your need and usecase.
It's respectable the you'd rather not repeat code just to get rid of an appBar when it's not needed.
Here's my suggestion, that would work with and take advantage of the framework rather than fight it.
Create your MultiPurposeSuperUsefulWidget, without a scaffold or appBar.
This widget can be shown easily without problems even needed with tabBar navigation.
The obstacle is wanting to use this in modal mode, you have the option to create this modal widget/screen template, that takes a final Widget widget constructor.
Customize this modal template in the way you like, and let's call it ModalTemplateScreen.
Finally, when you want your MultiPurposeSuperUsefulWidget to be displayed in modal style, navigate to ModalTemplateScreen(widget: MultiPurposeSuperUsefulWidget) and pass your reusable widget as an argument.
To set properties of your app bar based on modality you need to access the current Route and then check if the route was presented as a fullscreenDialog
isModal = (ModalRoute.of(context) as PageRoute).fullscreenDialog;

How do you reuse Flutter views created with MaterialPageRoute builder?

How do you reuse Flutter views created with MaterialPageRoute builder? Currently new views are created in the widget tree whenever Navigator.pushReplacementNamed is called. e.g. The following code will create 4 views in the widget tree:
Navigator.pushNamed(context, 'page1');
Navigator.pushNamed(context, 'page2');
Navigator.pushNamed(context, 'page1');
Navigator.pushNamed(context, 'page2');
I would prefer only two views in the widget tree - a single instance of both page1 and page2.
Is this possible?
push() and pushNamed() method recreate page over the current page you should use pushReplacement() and pushReplacementNamed() methods. However in this way you cannot use automatic back feature you should use pop() method or you should again some of push methods because when you you use pushReplacement() and pushReplacementNamed() methods previous page destroy and you should re-create manually.

Which function is called when a screen is opened after popping from navigation stack?

I have 2 screens - screen A and screen B. I navigate from screen A to screen B.
I want to take some particular action when I am coming BACK to screen A by popping out screen B from the navigation stack.
I know I can use didUpdateWidge but I can't figure out an efficient way of doing it.
Is using Inherited Widget the correct way here?
Navigator.push[Named] returns a Future that completes when screen B pops. So add the code you want to execute after the pop to then.
Navigator.pushNamed(context, '/someRoute').then((_) {/* do stuff here */});
Try to use WillPopScope. This widget allows to catch back button press.