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.
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.