Visual Programming with Flutter
A couple months ago when re-immersing myself in Flutter, I thought, “I really like Flutter but its declarative nature sometimes gets me confused on what Widgets go where, I wonder if there’s a way to make it less confusing.” I come from a teaching background so it seemed ripe for an experimental learning project to code without code.
AppInventor piqued my interest a bit, until I saw it uses a totally non-standard library for its code and interactions. Even though it’s an experiment, I wanted it to be grounded in code that would appear in a typical Flutter app. Looking into AppInventor did clue me in to Blockly, a library to generate code with interlocking building blocks.
There are a number of built-in blocks for common constructs like conditional statements, loops, various numeric operations, lists, and functions. For anything beyond that, you can create your own blocks using the Blockly Developer Tools.
The developer tools give you options to determine inputs/outputs and how the blocks will link with others. The generator stub is how that block will represent itself in final code.
Flutter Blockly Components
I started with a small set of Widget components initially trying to implement the inner core of a Scaffold before moving outward to encompass MaterialApp and even Stateless and Stateful widgets.
- FloatingActionButton / RaisedButton
The focus was less on trying to implement every single widget but to implement ENOUGH to give some customization and keep the app flow easy to read.
StatelessWidget and StatefulWidget
StatelessWidget and StatefulWidget were the first big challenge. First, they need to be classes which Blockly isn’t built to accommodate, aligning to a more functional style. Second, functions and variable declarations also default to being global. That’s great for a main function, not so much for a
build(BuildContext context) or whatever needed state variables.
Building out a component to model a class wasn’t too difficult for a StatelessWidget. It’s a matter of assigning a block of widgets to the build property and extrapolate that into a proper build function.
StatefulWidgets were a little bit trickier. The variables need to live inside the class derived from State. Inlining variables inside a class required a minor hack: creating a new block that would take raw code input. This is a minor misuse because any Blockly doesn’t know about any variable created this way. You lose the ability to use them in larger blocks. Once raw code, always raw code.
Another head scratcher was setState. Naturally I created a block for it but if you put that block in a function, it defaults to global and you’d get errors that it’s not a StatefulWidget.
This was the source of hack number two. The setState block would take in raw code and be directly assignable to onPressed on buttons.
Et voilà, I was able to make a Stateful Hello World (Counter) app without a single line of code. Well technically, 3 lines of code.
Here’s start to finish in a video (no audio). Empty
Scaffold instances have been created and
flutter run has been started and is pointing Flutter project that will receive updates from the web app. A similar flow is possible with Flutter Web however some widgets don’t map 1:1 from mobile to web.
And here’s how the finished app looks in blocks:
You can check out the code on Github.