Introduction to Flutter — How Does It Compare to Tauri?
Flutter gives you tight control of what is on screen, very much like a UI framework. If this is what you need, Google has you covered.
Aug 3rd, 2024 8:00am by
Image via Unsplash+.
The 250 seeds fly from the center to the circumference, or the other way around, reacting to the slider. So some are in the middle, the rest on the edge. It is clear there is some animation as the seeds seem to float serenely.
So from a design point of view, we have three models to consider. There is the structural model (where things are in the app and on-screen), the mechanical model (how it works logically) and the interaction model (responding to events).
Structurally, we have the title “Sunflower” at the top; we have the sunflower in the middle, composed of a dotted circle of seeds and the seeds in the center. Then we have the slider at the bottom with the text showing the number of seeds in the center (from a solitary seed at the left end to all 250 as we slide to the right end).
We know we will need math to calculate the position of the seeds on the circle, and their trajectory from and to the middle.
While there are a few ways we could represent this, it would seem reasonable to have an object for each seed, representing its position, and maybe its trajectory. Then we need an object to represent the sunflower’s state. And we vaguely understand that the slider will be some form of built-in control.
OK, let’s now take a look at the basic class outlines from the code on the left side of the Dartpad. As long as you are familiar with classes, objects and JSON layout, there is nothing weird in the code. In fact, if you’ve used a CSS framework like Bootstrap, you should feel at home.
import 'dart:math' as math;
import 'package:flutter/material.dart';
const int maxSeeds = 250;
void main() {
runApp(const Sunflower());
}
class Sunflower extends StatefulWidget {
...
}
class _SunflowerState extends State<Sunflower> {
...
}
class SunflowerWidget extends StatelessWidget {
...
}
class Dot extends StatelessWidget {
...
}
class _SunflowerState extends State<Sunflower> {
int seeds = maxSeeds ~/ 2;
@override Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
appBarTheme: const AppBarTheme(elevation: 2),
),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Sunflower'),
),
...
building) the app, and the AppBar contains a title, built of a Text object containing the title we recognized. This is within a Scaffold object.
The next simplest thing we know is that there is a slider. Where is that? Well, that is defined immediately after the AppBar within the body of the scaffold, within a Column object, as the child of a SizedBox:
... body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: SunflowerWidget(seeds),
),
const SizedBox(height: 20),
Text('Showing ${seeds.round()} seeds'),
SizedBox(
width: 300,
child: Slider(
min: 1,
max: maxSeeds.toDouble(),
value: seeds.toDouble(),
onChanged: (val) {
setState(() => seeds = val.round());
},
),
),
...
int seeds = maxSeeds ~/ 2;
...
class SunflowerWidget extends StatelessWidget {
static const tau = math.pi * 2;
static const scaleFactor = 1 / 40;
static const size = 600.0;
static final phi = (math.sqrt(5) + 1) / 2;
static final rng = math.Random();
final int seeds;
const SunflowerWidget(this.seeds, {super.key});
@override Widget build(BuildContext context) {
final seedWidgets = <Widget>[];
for (var i = 0; i < seeds; i++) {
final theta = i * tau / phi;
final r = math.sqrt(i) * scaleFactor;
seedWidgets.add(AnimatedAlign(
key: ValueKey(i),
duration: Duration(milliseconds: rng.nextInt(500) + 250),
curve: Curves.easeInOut,
alignment: Alignment(r * math.cos(theta), -1 * r * math.sin(theta)),
child: const Dot(true),
));
}
...
for loop. And the Dots are clearly held in the seedWidgets array. You can also see the trappings of the animation settings, including the path taken and time taken — if you have done any animation work you will recognize the easing value.
Conclusion
Hopefully, you can see from this post how Flutter compares with Tauri. Clearly the Dart language works within the widget Flutter models very tightly, to enable far greater control of what is on screen. We can tell a lot from the imports; the app only required the Dart math package and the Flutter materials for the widgets. We are being asked to think in terms of widgets — because the widgets are very much first-class objects, and the app is built around their interaction. We set up the initial conditions of the widget, and how they respond to change. The default behavior can be overridden to get what we need. Without further examination, we can see that Flutter is giving us very tight control of what is on screen, very much like a UI framework. If this is what you need, Google has you covered here.
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don't miss an episode. Subscribe to our YouTube
channel to stream all our podcasts, interviews, demos, and more.