Skip to content

Instantly share code, notes, and snippets.

@songyang-dev
Last active November 20, 2025 04:55
Show Gist options
  • Select an option

  • Save songyang-dev/6fc6d7351216d0d958ce57633fad02fb to your computer and use it in GitHub Desktop.

Select an option

Save songyang-dev/6fc6d7351216d0d958ce57633fad02fb to your computer and use it in GitHub Desktop.
Flutter Toronto X Maple Code

Flutter Tips

Now that you know how to start and run a Flutter app, let's explore what makes the framework special.

Widgets basics

Everything you see on the screen is made of widgets. A widget is a unit of the display. It can be a button, text, images, layout info, etc.

Widgets can contain other widgets. But every widget can only have one parent. They are organized in a tree. The root of the tree (the ultimate ancestor widget) is supplied to the runApp method in main.dart.

To avoid reinventing the wheel, Flutter has many widgets available. You need to read the docs to know what they do. Feel free to ask AI about which widget to use, but keep in mind the AI might not give you the latest info.

Common widgets

  1. MaterialApp: A theme and design widget that makes all its children follow the Material design.
  2. Scaffold: A layout widget for commonly used locations (app bars, sliding menus, floating action buttons, etc.). Without this, you would need to implement everything with Row and Column manually.
  3. Center: This centers whatever comes next, in all directions.
  4. Text: A content widget for text.
  5. Image: A content widget for images. The path it points to must be listed in pubspec.yaml.
  6. Padding, Container, SizedBox: Layout widgets that surround its child widget with empty space, each in a different way.
  7. GestureDetector: A handler widget. It listens for taps and clicks by the user on its child widget. This is how you would make an image clickable and react to the clicking.
  8. TextButton, ElevatedButton, OutlinedButton: Button widgets. They each look and feel different but do the same thing. In a way, they are pre-made versions of GestureDetector.

Stateless vs stateful widgets

Most widgets fall into two kinds. Stateless and stateful.

Stateless widgets are immutable. They will not change themselves.

Stateful widgets can change and hold a state to track the changes. Stateful widgets are composed of two classes, unlike stateless widgets which only have one.

/// This is the public facing class of a [StatefulWidget].
/// In Dart, visibility is public or private. Everything is public by default.
/// Private things start with an underscore _ like _FavoriteWidgetState().
class FavoriteWidget extends StatefulWidget {
  const FavoriteWidget({super.key});

  @override
  State<FavoriteWidget> createState() => _FavoriteWidgetState(); // constructor of a private class
}

/// This is the private class of a [StatefulWidget].
/// This holds the values of the state and the build method.
/// Flutter will call this build method whenever the state changes.
/// You trigger a state change with [setState()].
class _FavoriteWidgetState extends State<FavoriteWidget> {
  bool _isFavorited = true;
  int _favoriteCount = 41;
  ...
  
  @override
  Widget build(BuildContext context) {
  ...
  
  void _toggleFavorite() {
    /// [setState()] takes a void method as argument. This method
    /// will modify the state variables. Then, a "refresh" is triggered
    /// for the build method of the [StatefulWidget].
    ///
    /// Keep in mind all child widgets under this [StatefulWidget] will be
    /// "refreshed" as well. If you have a lot of widgets, this may cause lag!
    setState(() {
      if (_isFavorited) {
        _favoriteCount -= 1;
        _isFavorited = false;
      } else {
        _favoriteCount += 1;
        _isFavorited = true;
      }
    });
  }
}

Workshop Ideas

Welcome to our first workshop at Flutter Toronto x Maple Code! I'll introduce you to Flutter hands-on!

What is Flutter?

Flutter is a frontend framework that can be built into many platforms. It is mostly used for mobile apps, allowing you to just have one codebase instead of two (Android and iOS). Now, Flutter can be built into any 2D screen (web, Windows, TV, etc.)

Installation

Please have Flutter installed before coming. It can take a long time!

Suggested platforms:

  • Android or iOS
    • Note that only MacOS systems can build iOS apps
    • You also need an emulator. Alternatively, you can use your real phone with a USB cable connected to your laptop, after you give permission in your settings.
  • Web: Chrome
    • The easiest to set up

Suggested coding setup:

  • VSCode with Flutter extension

How to do the workshop

  1. Take a look at the ideas below and decide which one you want to try.
  2. Find other people at the event who are also interested in the same idea.
  3. Team up and start building!
    • I’ll be moving around to help you out.

Ideas

  1. Cookie clicker
  2. Anything else you want to do 🙂

How to start

Double check your installation

Run flutter doctor in the terminal (from anywhere).

If no issues are found, you are good! If you have issues and it is related to a platform you are not interested in using, you can ignore it.

Initializing a Flutter project

  1. Navigate to the folder where you want to create the project.
  2. Run flutter create your_project_name. Replace the name with what you want!
    • Alternatively, you can clone someone else's repo if you are working with them.
  3. You can open the project inside your IDE.
  4. cd into your newly created project folder.
  5. If targeting mobile, boot up your emulator or plug in and set up your phone.
  6. Run your project with flutter run.
    • The first time will take a minute!
    • Stop it with Q or an interruption signal (Ctrl+C or Cmd+C).
    • If your Android emulator is taking up too much or too little screen space, you can use Ctrl+Down/Up to scale it.

Understanding the structure of a Flutter project

After being created, the project is set up to target every platform Flutter is capable of.

Screenshot 2025-11-18 234357

You can delete the folders of OS platforms you don't want to build for. I suggest leaving them as is unless it is causing issues.

pubspec.yaml

This is the core identity of your Flutter project. It details the dependencies and the core settings of your project.

assets/

By convention, this is where you put your images, audio file, etc. You need to specify the asset paths inside the pubspec.yaml because Flutter doesn't know.

lib/

This is where all the Dart code goes. Flutter uses Dart! It is similar to Java and Typescript.

lib/main.dart

This is the entry point script for your program. It is a must-have file to compile the project properly. By default, this file contains a generic app that you can run with flutter run. Play around with it for a while. Then, I suggest deleting its content to start from scratch so you learn better what goes where.

The bare essential of a main.dart for the Hello World program is:

import 'package:flutter/material.dart'; // Access all the Flutter "Widgets"

// This is absolutely mandatory in Flutter and Dart.
void main() {
  runApp(const MyApp());
}

// This is a widget you define.
// This widget is the root of your application.
// Widgets are organized in a tree. The Flutter runtime uses your tree to show things.
class MyApp extends StatelessWidget {
  const MyApp({super.key}); // This is a constructor method.

  // This is a required method to make the class work within Flutter.
  // It comes from [StatelessWidget].
  @override
  Widget build(BuildContext context) {
    // You need to define a [TextDirection] to make it run.
    // Flutter does not assume text is left to right.

    // If you don't define the direction, you will get a runtime error.
    // The screen will turn red with yellow text!
    return Text("Hello world", textDirection: TextDirection.ltr);
  }
}

What this looks like when run. You will notice that "Hello world" is not entirely visible on mobile, due to the shape of the device. Look closely, it is in the top left corner.

Screenshot 2025-11-19 001718

A minimalist and stylish Hello World

Here is a more elegant Hello World program. Your lib/main.dart becomes:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // The return statement can get nested deep easily! I suggest you download 
    // the Flutter extension in VSCode to manage this easier. The extension 
    // can help you wrap widgets without you having to find the brackets.

    /// [MaterialApp] is a theme widget that follows the Material design,
    /// is created by Google to reflect a "good" UI/UX.
    ///
    /// Usually, you only have this widget once in your entire app and it is at
    /// the very beginning.
    return MaterialApp(
      /// The [home] argument is to define the home path (/) of the app.
      /// MaterialApp comes with a router.

      /// [Scaffold] is a layout widget to place things in commonly used
      /// places. For example, the app bar, the body, floating action button, etc.
      home: Scaffold(
        /// The [body] here represents the location of the main body of a screen.
        
        /// [Center] is a positional widget that centers its child widget in all
        /// directions (horizontal and vertical).
        body: Center(
          /// [child] is the default name for arguments taking widgets.

          /// [Text] is a widget to represent text. Because it is inside a
          /// [MaterialApp], there is no need to specify the text direction.
          /// It is assumed to be left to right.
          child: Text("Hello World"),
        ),
      ),
    );
  }
}

When rendered on iOS, it looks like this. (The borders appear or not depending on how you take the screenshot.)

Simulator Screenshot - iPhone 16e - 2025-11-19 at 22 58 07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment