I am Jimmy lau, I am an Android developer. Flutter got popular this day so my company decided to do a little project on Flutter. I started learn flutter in recent days.
I am here to talk about a specific method which I found it is really common on Flutter -> Controller 😊
If you had experience on Android, you must be familiar with the declarative programming.
View view = View();
view.target = 666;
Here is a quick sample of how Android modifies field inside your view.
But Flutter as we know is reactive programming (everything is a widget 😊)
We do not modify your widget directly in this way.
Widget widget = SmallWidget();
widget.height = 123;
The code above obvious doesn’t work, widget does not give you the access to control view property, it is just a wrapper for Element.
Also the attributes inside your widget in immutable.
What we can do is do some hacking on Element, which is your buildContext
context.findRenderObject().size.height
Element object has a reference of its renderObject, you can get something like widget size or some other object related to rendering view.
Well, for developer, if we want to change attribute on your StatefulWidget, you can simply call setState() , it tells the flutter framework to rebuild your widget.
But what if we have a complex widget tree and the widget we want to target is too deep on the widget tree ?
Controller is here to help.
...
ScrollController _scrollerController = ScrollController();child: ListView(
controller: _scrollerController,
...)
We must write this code really often.
We can add a listener callback every time a specific event happened inside the widget or we can change attribute in their widget directly through controller.
For instance
_scroller.initialScrollOffset = 0;
This is super flexible if you are writing a flutter library and you want your users to dynamically control something in your widget.
Here is a simple sample for controller pattern.
class ChristmasTree extends StatefulWidget { final Colors color; ChristmasTree({this.color}); @override State<StatefulWidget> createState() { throw UnimplementedError(); }}class TreeState extends State<ChristmasTree> { @override Widget build(BuildContext context) { return Container(); }}
We have a statefulWidget only with a color attribute on it.
What if we want to modify the color outside ?
We add a controller on it.
class ColorController { ValueChanged listener; void initState(ValueChanged listener) { this.listener = listener; }void changeColor(Color color) { listener (color); }}
Add controller as parameter
final ColorController controller;ChristmasTree({this.color, this.controller});...
@overridevoid initState() { listener = (color) {setState() { this.color = color;}}; widget.controller.initState(lisnter);}; super.initState();}
Finally, if we want to change color outside, we can simply call the controller !
TreeController controller = TreeController();
controller.changeColor(Colors.green);
That’s it ! Thank you for reading. If you like this article, please clap for a second, I would continue to publish flutter article like this.