Is it possible to implement a Hero Animation in flutter but instead of being controlled by Navigator, be controlled by a custom AnimationController.
This is for a use case needs to go inside another element rather than a new screen as is the case with Navigator.
Alternatively, is it possible to directly inject a widget into an overlay that is fixed permanently elsewhere on the screen preserving the state, logic and controllers of where it was initially declared.
Imagine I have content that changes on a page based on a certain user interaction but still should animate a transition of a sliver app bar as if a new screen has entered when it had not.
In laymen's terms, I want to declare a widget wherever I happen to declare it but not actually render there. IT should render instead in a targeted location but still maintain any state or controllers it obtained or inherited from the position in which it was actually declare.
Related
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.
I have designed a simple dashboard menu using valuelistenablebuilder which basically changes based on the selected icon.
Here's an example of how it looks
Whenever i click one of the dashboard buttons (cards inside a gridview), it updates the listennablevalue, and thus it leads to a similar view but the number of buttons (and the content within the button) changes.
however, there is no transition or animation as the basic material pageroute given the builder is just rebuilding the view.
Is there a way to add a smooth transition using this listener?
I'm trying to find a way to check the visibility of a Flutter widget when it's either off screen or when it's obscured by another, for example Drawer, Dialog or BottomSheet.
visibility_detector helps with checking whether it's on the screen or not but does not work with the second use case (known limitation).
Is there a lower lever api that I can use to check whether a widget is actually visible to the user?
My use case: I'm adding a widget to the Overlay when something external happens (similar to Tooltip but not on long press). If the user opens for example the Drawer, the widget will appear on top. I want to detect that the child is not visible and delay or cancel the action.
Do I understand your problem?
You have a widget you want to always be on top?
You want the user to interact with that widget first before doing other things?
Use design patterns to make coding easier, your users will thank you.
You can show a Dialog on-top of other widgets with the showGeneralDialog or showDialog functions. Because Dialogs are a design-pattern used in many apps, users will already know how to use them.
Define app behavior with explicit state.
It is too hard to derive app behavior from rendered UI, not all devices are the same size and shape. This means you should try to write a variable that describes your situation and then write the code you need to make that variable's value correct. It sounds like you want a variable like bool overlayIsShowing.
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.
Say I have a Flutter app with two screens - screen A and screen B. Screen A is just a ListView that displays a list of items but needs to perform a network call whenever the list changes and then update the list. Screen B can modify the list of items but I want screen A to only perform the network call when screen A is in the foreground and being displayed. As far as I can tell, I cannot do this easily. Screen A is not disposed and reinitialized when navigating to and from screen B. It would very helpful if StatefulWidget had onForeground and onBackground methods to override, but they do not. This problem is not exclusive to navigation either, but this same problem presents itself when using PageView with full-screen pages. Is there some proper/standard way of implementing this?
My current setup is as follows: I let the parent widget to both screen A and B hold the list in a ValueNotifier and pass it to both screens when constructing them. Then, screen A listens for changes on the ValueNotifier and performs a network call whenever it does. So, in order to determine whether screen A is in the foreground/background, I will have to start/stop listening for changes before/after navigating. But I haven't started implementing this, as I think it will get complicated when widgets far down the widget tree trigger the navigation or other widgets need to know whether they're in the foreground/background.
Another option I've thought of is instead of observing for changes in the list, I could rather just return a result from screen B saying whether or not the list changed and react then. But I can think of many ways this can complicate my code as well since my real app involves more than just one dependency. I would have to create a custom result class for each screen containing a record of all the data that changed then it would be tedious if I want to add more data in the future. And how would I handle navigation to screen B then screen C? The result would have to be retained and passed down so screen A can react to changes made by screen C. I would also have to ensure all calls to Navigator.pop contained the result, and override back button presses to pop with the result. And I'd also have to ensure that the result makes it to the proper widgets that need to react to changes.
Am I just missing something simple to accomplish this? I am not the most experienced with Flutter and I wouldn't be surprised if there's some easy solution I haven't learned yet.
Edit: After some more testing, it appears AnimationController does something similar to what I need with the vsync parameter, in that it does not update when the State is in the background or when it is not being drawn. So, I could use SingleTickerProviderStateMixin on screen A's state, then use createTicker to create a Ticker, and then check if the Ticker.isTicking whenever the list changes. If it is ticking, screen A is in the foreground, otherwise it is in the background. Although I'm not sure if this is a good approach, since it appears Ticker's are really only used for Animations and there's nothing documented for a use case like mine.