Flutter: Using expansion panel with navigator animate the AppBar when expansion panel is open - flutter

In one section of a client's app an expansion panel / accordion is used to open some content. At the same time the AppBar is supposed to animated as is a new route has been pushed but the new route's content should display in the body of the expansion panel.
I have been able to implement this by creating an entirely independent Widget and using a state management library but it is not a tidy solution.
I wondered if it is possible to use the App's main Navigator but not remove the current route's body. This cannot be done with a nested navigator either as the AppBar uses Hero tags that are not reflected between Navigator's.
Is there a simple way to achieve this without using entirely customised state management.

Flutter's in built Navigator, even Navigator 2.0, is well known to not be a particularly friendly interface to use, so I'd recommend the use of a community library that makes things easier.
Auto Route is a popular solution that I use personally and can attest to its quality. For your particular problem it offers navigation observers which you can register. You could use this to trigger the animation of your app bar when the new route is pushed.
It will be a little bit of effort to replace your current navigation with a new library but I'd imagine you'll end up with a cleaner solution at the end instead of customized state management.

Related

Flutter Recreating the Hero Transition replacing Navigator with a custom Animator

Looking at the Flutter Hero Transition, it appears to move the tagged Widgets to an Overlay class that exists in all Navigator Widgets but sits above the main content in the stack.
If this is correct, it allows the Hero to widgets to still respond to the Route scope and its animators but exist above the actual route content. How is this actually done efficiently? Surely this involves taking an entire Widget and storing it in a state for the duration of the animation. That Widget still has to respond to intrinsic responses from its original position such as slivers responding to active scroll actions.
Recreating this could be done with state management but I wondered how the standard hero actually does this. It seems like Widgets are effectively duplicated and then conditionally rendered on the screen defaulting to the overlay during the route animation and swapping out the original widget with an Offstage or similar. Is this how it is done?
The reason for trying to understand it is the need to replicate this behaviour in situations where Navigator is not an effective use case for a transition taking place internally on a page. I built an accordion style navigator but still want a hero transition to take place on the AppBar / NavigationBar. I know that this could be done with Navigator but it doesn't suit the use case. I could also predefine the AppBar content for each internal navigator state of the accordion but that is a lot of additional code.

Does MVVM require to remove all logic from the Widgets?

I'm having confusion regarding the correct implementation of MVVM architecture in a flutter.
Does MVVM require separating just the UI calls from the UI or
separating the complete logic of the widgets, even if it is to update
a CheckBox?
If using setState does not raise performance issues, should we use it when following MVVM architecture?
If it is okay to have some logic inside of widgets, to what extent
should we do that?
Yes obviously , I suggest you to study Clean Architecture, Basically concept is that, You have to create ViewModel for every screen.
Screen will contain all the Widgets (View)
View Model will contain all functionality and variable which will be hold value which used in Screen (View)
It is perfectly okay for the widget to manage its state internally. It wouldn't make sense e.g. ListView not to manage its scrolling state. The same obviously applies to custom widgets.
See Differentiate between ephemeral state and app state for more information.

Flutter: Using Hero without Navigation

I have an app that uses a BottomNavigationBar to switch between two screens with their own navigation stack. I would like to use the Hero tag to create a custom transition between the two, but since I don't use navigation, but rather change the state to switch between screens, I'm not sure if this is possible at all.
Is there any way to recreate the transitions provided by Hero without using Navigator?
The Hero widget is not what you are looking for. Try the animations package made by the flutter team. Here the link to this package.
Is not easy to use, but get a try, or you can use the default Navigation built in.

Tracking screen views in Flutter with Firebase Analytics

What is the best location for manually logging a screen view in Flutter with an analytics package (in my case I am using Firebase Analytics, eg. track screens)?
Looking at the Flutter lifecycle, it's not clear where it makes sense to track a screen view.
For a StatelessWidget, I think build() might make sense as I guess it's only called one time per screen view.
What about for a StatefulWidget though? In this case build() would not be useful as it could be called many times. Other candidates are initState(), createState() or the constructor which all appear to only be called once although I'm guessing they may all be called more than once per screen view as widgets up the hierarchy are re-built.
The answer is: it depends. For a StatelessWidget, it might be suitable to have an Analytics event in build(), but only if the parent widgets are not re-built frequently. For a StatefulWidget the same applies but you also have to factor in re-builds due to state change (which are, more than likely often).
Really, the safest path is not to call Analytics events in any parts of the widget lifecycle, but instead on the UI event that might trigger a screen, for example, an edit button that opens up an edit screen. However, the problem with that approach is that the screen might be opened from a variety of locations within the app (meaning you have to duplicate Analytics calls across all those locations).
This means the best option is probably to tie Analytics to PageRoute transitions so that it is called consistently whenever a page route is executed. This is demonstrated in the docs. This will miss tracking screens within a tab bar and other types of UI navigation but as the docs also say, one way to handle this is to implement RouteAware and subscribing it to FirebaseAnalyticsObserver (example tabs implementation).

Clone a panel of widgets

is it possible in GWT to clone a panel? If so, are all the handler settings copied as well?
Basically I have a Panel full of controls, all laid out, I want to copy it and pop it up in a PopupPanel without having to go through the code that created the controls in the first place.
I got as far as DOM.clone(), and this message post. But there is no wrap() in Widget, UIObject etc. setElement() is protected.
Quick way to build a Widget from a DOM element:
Widget widget = new Widget () {{
setElement(myElement);
}};
But no, AFAIK DOM.clone() isn't going to copy attached handlers as well. I suspect this won't work as well as you're hoping.
Have you considered creating a new GWT widget, consisting of all of those controls? That way you can host the widget panel in both places without resorting to cloning it. (And possibly saving you subtle bugs in the process.)
Create a new class with all the controls and other features that you have in your panel and treat this as a new widget... Now you don't have to worry about cloning them, you can use this as a regular widget in your program (you can initialize it the same way you do rest of the widgets)... This is how i started off for one of my projects, where i was trying to clone a panel...