Post

Getting Started With Flutter - Basics, Project Structure & How It All Works

Explore Flutter basics, core concepts, and the default project structure to help you start building cross-platform mobile apps quickly.

Getting Started With Flutter - Basics, Project Structure & How It All Works

Flutter is an open-source UI framework developed by Google. It allows you to build apps (using a single codebase) for:

  • Android
  • iOS
  • Web
  • Desktop (Windows, macOS, Linux)

Flutter uses the Dart programming language, and unlike other cross-platform solutions, it renders its own UI using a high-performance graphics engine (Skia). Flutter has become one of the most popular frameworks for building cross-platform mobile apps thanks to its speed, flexibility, and native-like performance.

Flutter Basics

Everything Is a Widget

In Flutter, literally everything you see on the screen—and even things you don’t—is a widget. Widgets are the fundamental building blocks of a Flutter applications. Flutter doesn’t separate views, controllers, and layouts. Instead, it uses widgets for everything, including:

  • Structure (e.g., Scaffold, AppBar)
  • Layout (e.g., Row, Column, Stack)
  • Styling (e.g., Padding, Align, Container)
  • Interaction (e.g., GestureDetector)
  • Presentation (e.g., Image, Text)

Flutter has two main widget categories:

Stateless Widgets

These widgets don’t change once they’re built. They render the same way as long as their input (properties) stays the same. Examples include:

  • Text
  • Icon
  • RaisedButton (or ElevatedButton)
  • Container

Stateful Widgets

These widgets can change over time because they hold mutable state. Examples include:

  • Forms and input fields
  • Animated widgets
  • Pages that update after a network request
  • Buttons that trigger a UI change

Stateful widgets contain a State object, which stores the dynamic data. When data changes, Flutter rebuilds the widget tree efficiently via setState().

Common Widget Categories

Layout Widgets

Control how widgets are arranged:

  • Row
  • Column
  • Expanded
  • Stack
  • ListView

Styling & Decoration Widgets

  • Padding
  • Align
  • Container
  • SizedBox
  • Center

Structural Widgets

  • Scaffold
  • AppBar
  • Drawer

Interactive Widgets

  • GestureDetector
  • InkWell
  • TextField
  • Switch

Visual Widgets

  • Text
  • Image
  • Icon
  • Card

Flutter promotes composition over inheritance. Instead of creating one huge, complicated widget, you combine multiple small widgets to build a complex UI.

For example, a simple card might be built from:

  • Container (layout)
  • Row (horizontal layout)
  • CircleAvatar (image)
  • Text widgets (labels)
  • Padding (spacing)

Dart Language Essentials

Dart is a modern, object-oriented language used to build Flutter apps. It features a clean syntax, sound null safety, and strong typing with optional inference. Everything in Dart is an object, and it supports classes, functions, async/await, and collections like lists and maps.

Class-Based Language

All objects are instances of classes, and every class ultimately inherits from the Object class.

1
2
3
4
5
6
7
8
9
class Person {
  String name;
  Person(this.name);
}

void main() {
  var person = Person("Jenny");
  print(person.name);
}

Variables and Data Types

Dart supports static typing but also lets you use type inference with var.

Common Data Types:

  • int → Whole numbers
  • double → Decimal numbers
  • String → Text
  • bool → True/false values
  • List → Arrays
  • Map → Key-value pairs
  • dynamic → Any type (not recommended unless necessary)

Null Safety

Dart uses sound null safety, meaning variables can’t be null unless explicitly allowed.

1
2
String name = "John";      // Cannot be null
String? nickname;          // Can be null

Functions

Functions in Dart are first-class objects — you can pass them as arguments or assign them to variables.

1
2
3
4
5
6
7
void greet() {
  print("Hello!");
}

int add(int a, int b) {
  return a + b;
}

Async and Await

Dart has built-in support for asynchronous operations, crucial for Flutter apps that handle network calls and long-running tasks.

1
2
3
4
5
6
7
8
Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return "Data loaded";
}

void main() async {
  print(await fetchData());
}

Imports

To use libraries or files:

1
2
import 'dart:math';
import 'package:flutter/material.dart';

Default Flutter Project Structure

When you create a new Flutter project, you’ll see this structure:

1
2
3
4
5
6
7
8
9
10
11
12
my_app/
│
├── android/       # Android-specific configuration
├── ios/           # iOS-specific configuration
├── lib/           # Main Dart code lives here
│   └── main.dart  # Entry point of the app
│
├── test/          # Unit and widget tests
├── web/           # Web-specific files (optional)
│
├── pubspec.yaml   # App dependencies & assets
└── README.md

Here’s what the most important folders/files do:

lib/

  • This is where application’s logic and UI code go.
  • main.dart contains the main() function—the app’s starting point.
  • Typically you create folders like screens/, widgets/, models/, and services/ as your app grows.

pubspec.yaml

This file manages:

  • Dependencies (packages)
  • Assets (images, fonts)
  • App metadata (name, version)

android/ and ios/

  • These contain platform-specific native code and configurations.

test/

  • Used for unit tests and widget tests.
This post is licensed under CC BY 4.0 by the author.