Closed gemilangpermata closed 4 years ago
+1
@rafaelcmm can you answer this? Why was this removed?
Hi, nice work here.
One question, how to get controller getter in v4 since it was removed? I want to get the controller in initState of view.
Hi, I just submitted a pull request that will fix this request.
For resume, I'm adding a way to get access to controller on initState
lifecycle. For that, just implement over initViewState
and do what you want with the injected controller.
The main goal of the removal of controller
from the ViewState
was to prevent "bad" usage of the controller, and to be able to remove the full re-render of the widget tree. Now we can have three scenarios where the access of the controller is pertinent.
On initViewState
, where you can access the early initialization of the controller and perform actions you want on this state.
On StatelessWidget
through ControlledWidgetBuilder
. You can use it to create your stateless widgets outside the ViewState
(for example, on a widgets folder inside your page) and have access to the last state of the controller, ensuring that the widget will re-build only when refreshUI
is triggered, and will rebuild only where the controller is used.
On StatefulWidget
through FlutterCleanArchitecture.getController
.
With those changes we are able to optimize at maximum the re-build cycle of child widgets of the page, only re-rendering on places that directly depends on controllers variables.
Any questions, I'll be happy to answer or provide other ways to access the controller when necessary.
IMPORTANT
This PR opens a possibility for a bad practice:
class State extends ViewState {
Con _controller;
// THIS IS BAD. YOU WILL HAVE AN INSTANCE OF AN UN-UPDATED INSTANCE OF THE CONTROLLER AND CHANGES ON IT WILL NOT REFLECT ON YOUR WIDGETS.
void initViewState(Con controller) {
_controller = controller;
}
}
Thank you for your contribution
@rafaelcmm is there a better place to put AnimationController
? Like this example: https://github.com/ShadyBoukhary/Axion-Technologies-HnH/blob/7ebb03e9c0511f1ec2649d6bdd123318ada191d5/lib/app/pages/splash/splash_view.dart
For example, to avoid using initViewState
how can I put it in my Controller
?
You can try do something like this:
Declare those inside splash_controller
final AnimationController animationController = AnimationController(duration:Duration(seconds: 1));
Animation<double> animation = CurvedAnimation(parent: animationController, curve: Curves.easeIn);
Then on initViewState
@override
void initState(Con controller) {
super.initViewState();
controller.initAnimation();
}
Wrap your animated widget inside a ControllerWidgetBuilder
ControlledWidgetBuilder(
builder: (ctx, controller) {
return FadeTransition(
opacity: controller.animation,
child: Image(
image: AssetImage(Resources.logo),
width: 200.0,
))
}
)
Now, on your initAnimation
void initAnimation() {
animation.addStatusListener((status) {
if (!isLoading) {
animationController.stop(canceled: true);
} else if (status == AnimationStatus.completed) {
animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
animationController.forward();
}
});
animationController.forward();
refreshUI();
}
To resume what is being done:
ControlledWidgetBuilder
, to ensure that the animation state will change whenever the controller changes. This approach may be done to every other thing that depends on a controlled variable. Please try this approach and give me some feedback if you achieve what you want using this approach (please adapt it to your needs)
I'll try it!
@rafaelcmm AnimationController requires vsync though and we need a state with TickerProvider. How do we do that in controller?
Hi, nice work here.
One question, how to get controller getter in v4 since it was removed? I want to get the controller in initState of view.