In this lesson, we'll create and run your first Flutter application from scratch, explore the project structure in depth, and understand the fundamentals of how a Flutter app starts. By the end of this lesson, you'll master the basic workflow of Flutter development.
I. Creating a Project with the flutter create Command
Flutter provides a convenient command-line tool to quickly generate a standardized project structure.
Step 1: Open Terminal/Command Prompt
- Windows: Use Win + R, type cmd to open Command Prompt, or use PowerShell
- macOS/Linux: Use Spotlight to search for Terminal or open it from your Applications folder
Step 2: Create the Project
Enter the following command in your terminal:
flutter create my_first_app
- flutter create is the command to create a new project
- my_first_app is your project name (use lowercase letters with underscores between words)
After executing the command, Flutter will automatically create a complete project structure, including configuration files for iOS and Android platforms. The creation process may take a few minutes, depending on your internet speed (as it needs to download necessary dependencies).
Step 3: Navigate to the Project Directory
Once created, use the cd command to enter the project folder:
cd my_first_app
II. Running Your First Application (Emulator/Physical Device)
Now that we've created our project, we can run this default Flutter application on an emulator or physical device.
Preparation
- Ensure you have installed and configured your Flutter development environment (check with flutter doctor)
- Prepare a running device:
- Emulator:
- Android: Launch an Android emulator through Android Studio
- iOS (macOS only): Launch an iOS simulator through Xcode
- Physical Device:
- Android: Enable USB debugging mode and connect to your computer via USB
- iOS (macOS only): Connect your iPhone via USB, requires developer account configuration in Xcode
- Emulator:
Running the Application
In your project directory, execute the following command:
flutter run
Flutter will automatically detect available devices and install the application. The first run may take longer as it needs to compile native code and download dependencies.
When successful, you'll see a default counter app on your device, featuring a number display and a clickable button.
Common Run Commands
- r: Hot Reload - Quickly apply code changes while preserving app state
- R: Hot Restart - Restart the app, clearing app state
- p: Display grid overlay
- q: Quit run mode
III. Project Directory Structure Explained
Let's explore the Flutter project directory structure and the purpose of each component:
my_first_app/
├── .dart_tool/ # Files generated by the Dart toolchain
├── .idea/ # Android Studio configuration files (Windows/macOS)
├── android/ # Android platform-specific code and configuration
├── build/ # Compiled output files
├── ios/ # iOS platform-specific code and configuration
├── lib/ # Dart source code (core directory)
│ └── main.dart # Application entry file
├── linux/ # Linux platform code (optional)
├── macos/ # macOS platform code (optional)
├── test/ # Test code directory
├── web/ # Web platform code (optional)
├── windows/ # Windows platform code (optional)
├── .gitignore # Git ignore file configuration
├── .metadata # Flutter project metadata
├── analysis_options.yaml # Dart code analysis configuration
├── pubspec.lock # Dependency version lock file
├── pubspec.yaml # Project dependencies and configuration
├── README.md # Project documentation
Key Directories and Files Explained
- lib Directory
- This is our primary development directory where all Dart source code resides
- main.dart is the application entry point, containing the main() function
- As your project grows, you'll create more Dart files and subdirectories to organize your code
- pubspec.yaml
- The project configuration file, similar to package.json in frontend or pom.xml in backend development
- Contains basic information like project name, description, and version
- The dependencies section declares packages your project depends on
- The flutter section configures resource files (images, fonts, etc.)
- After modification, run flutter pub get to update dependencies
- android Directory
- Contains Android platform-specific code and configuration
- Used when you need to make Android-specific configurations or developments
- Includes AndroidManifest.xml, Gradle configurations, etc.
- ios Directory
- Contains iOS platform-specific code and configuration
- Used when you need to make iOS-specific configurations or developments
- Includes Info.plist, Podfile, and other configuration files
- test Directory
- Used for storing test code
- Supports unit tests, widget tests, and integration tests
IV. Entry Function main() and runApp() Principles
Let's open the lib/main.dart file and analyze the startup process of a Flutter application:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
// ... Some code omitted
The main() Function
- The main() function is the entry point for all Dart programs, where execution begins
- In Flutter, the primary role of main() is to start the application
void main() {
runApp(const MyApp());
}
The runApp() Function
- runApp() is a core function provided by the Flutter framework, defined in package:flutter/material.dart
- Its role is to take a given Widget as the root Widget of the application and attach it to the screen
- runApp() creates a Flutter engine instance, initializes the application, and starts the rendering process
- It accepts a Widget parameter that becomes the root node of the entire application's Widget tree
Application Startup Process
- Execute the main() function, the starting point of the Dart program
- Call runApp() within main(), passing in the root Widget (in our example, MyApp)
- The Flutter engine initializes and prepares the rendering environment
- Build the entire Widget tree starting from the root Widget
- Render the Widget tree to the screen
Widget Tree Structure
In the default project, the Widget tree structure is:
-
MyApp (StatelessWidget) → Root Widget of the application
- MaterialApp → Provides Material Design application framework
- MyHomePage (StatefulWidget) → Application's home page
- Scaffold → Provides basic page structure (AppBar, Body, etc.)
- AppBar → Top navigation bar
- Center → Centering layout widget
- Scaffold → Provides basic page structure (AppBar, Body, etc.)
- MyHomePage (StatefulWidget) → Application's home page
- MaterialApp → Provides Material Design application framework
-
Center → Centering layout widget
- Column → Vertical layout widget
- Text → Text widget
- FloatingActionButton → Floating button
- Column → Vertical layout widget
V. Hot Reload Principles and Practice
Flutter's Hot Reload is a powerful feature that allows you to quickly apply code changes to a running application without restarting it, significantly improving development efficiency.
How Hot Reload Works
- When you modify code and trigger a hot reload, Flutter incrementally compiles the changed Dart code
- Sends the compiled code to the running Dart Virtual Machine (VM)
- The Dart VM reloads the updated code
- The Flutter framework rebuilds the Widget tree while preserving application state
Using Hot Reload
- Ensure your application is running (flutter run state)
- Modify your code (e.g., change text content or colors)
- Press r in the terminal or click the Hot Reload button in your IDE
Try changing primarySwatch: Colors.blue to primarySwatch: Colors.red in main.dart, then trigger a hot reload to observe the theme color change.
Top comments (0)