DMarlon Studio

Chapter 10

Mobile apps with Flutter

Screens in the style of FlutterFlow, logic in Dart and a built-in phone simulator.

Create a Flutter app

When creating the project, choose Flutter (mobile). The Design tab is an editor in the style of FlutterFlow: on the left, the screens and the widget tree of the selected one; in the middle, the palette and the phone with the preview; on the right, the properties of the selected widget (or of the screen and the app).

  • A widget from the palette is added inside the selected one if it is a column, a row or a list; otherwise, after it. Select it by tapping it on the phone or in the tree; Up, Down, Duplicate and Delete are above the tree.
  • Widgets: column, row, list, card, container, padding, center, expanded, text, button, icon button, text field, list tile, check box, switch, chip, icon, image, progress, divider and spacer.
  • + in Screens opens the gallery: a blank screen or one of the 20 most used templates (sign in, sign up, reset password, welcome, home, list, detail, profile, edit profile, settings, notifications, messages, chat, search, cart, checkout, order confirmed, dashboard, contact and help), with its preview. Their buttons write to Output (debugPrint) until you bind them to App.
  • Each screen has a name, a title, a top bar, a floating button and, if it is opened with something (a shipment, for example), the type it receives.

Logic and bindings

The Code tab is lib/app.dart: an App class with the app data and methods. The screens use it as app and redraw when it calls notifyListeners(). Generated Dart shows lib/main.dart, which the studio writes from the screens.

class App extends ChangeNotifier {
  final tasks = <Task>[];
  String newTask = '';

  void add() {
    tasks.insert(0, Task(newTask));
    newTask = '';
    notifyListeners();
  }
}
In the propertiesExample
A text with values${item.title} · Hello, ${app.name}
An expression (with =)=item.done · =app.color(item.status)
An actionapp.add() · go:Detail(item) · app.create(); back
A bound listItems: =app.tasks; its first child repeats with item
A text fieldSaves to: app.newTask
Visible if=app.tasks.isNotEmpty
A conditional actionif (app.signIn()) home:Catalog
Bar buttonsshopping_cart|go:Cart|${app.items} (icon, action and badge)

Desktop

  • Choose Flutter (desktop) when creating the project: the same editor, with the preview in a macOS window.
  • Menu (app properties): one line per screen, Screen|icon|text. In a wide window it is a side bar (NavigationRail); in a narrow one, the bottom bar. It also works in mobile apps.
  • Run (F9) opens the app in its native window (macOS, Windows or Linux), and saving reloads it.
  • Example: Inventory, with a dashboard, products, a product page with stock and new products.

FalconDatabase and Firebase

In the app properties (with no widget selected), Database → Connect to chooses FalconDatabase (server, project reference and anon key) or Firebase (project ID and web key). The studio generates lib/db.dart with the same shape for both, and App uses it with import 'db.dart';.

Future<bool> signIn() async {
  try {
    await db.signIn(email, password);
    notes = await db.table('notes').list(order: 'id.desc');
    notifyListeners();
    return true;
  } on DbError catch (e) {
    error = e.message;
    notifyListeners();
    return false;
  }
}
  • db.signIn(email, password), db.signUp(…), db.signOut() and db.user: the session.
  • db.table('t').list(where: {…}, order: 'field.desc', limit: 20), get(id), insert({…}), update(id, {…}) and delete(id). In where, a value or an operator such as gte.10.
  • Actions can wait: if (await app.signIn()) home:Notes.
  • Only the public key (anon or the web key) goes inside the app; access rules are set by the database.
  • Example: Cloud notes, with login and the FalconDatabase notas table.

The simulator and export

  • Run (F9) compiles the app with Flutter for the web and opens it in the studio simulator: a phone frame (iPhone, Pixel, Galaxy or iPad mini) you can rotate. No Xcode or Android needed.
  • When you save, the app is recompiled and the simulator reloads by itself.
  • What print or debugPrint writes shows in the Output tab, and errors with their lib/app.dart line.
  • pub.dev packages (for example, shared_preferences: ^2.3.0) are added in the app properties.
  • Export the Flutter project leaves pubspec.yaml, lib/main.dart and lib/app.dart: with flutter create . and flutter run it opens on the phone, in Android Studio or in VS Code.
  • Examples: Shop with login (login, catalog with search and categories, product page, cart with quantities and checkout), Shipments (summary by status, filtered list, detail with tracking and new shipments) and Tasks (add, check, filter and delete, saved on the phone).