#flutter /
Flutter Introduction: Dart Language Basics and Your First App
From Dart language basics to Flutter development environment setup, step-by-step guide to creating your first Flutter application and mastering core Flutter development concepts.
Goal
Flutter is a cross-platform UI framework from Google, developed using the Dart language, enabling you to build iOS, Android, Web, and desktop applications from a single codebase. This article starts from Dart language basics, explains Flutter development environment setup and creating your first application, helping developers quickly get started with Flutter development.
Background
Why Choose Flutter
Flutter's core advantages:
- One codebase, multiple platforms: iOS, Android, Web, Windows, macOS, Linux
- High performance: Custom rendering engine, no dependency on native controls
- Rapid development: Hot Reload enables second-level previews
- Rich component library: Material Design and Cupertino style components
- Google support: Strong community and continuous updates
Dart Language Characteristics
Dart is Flutter's development language with the following features:
- AOT + JIT compilation: JIT during development enables Hot Reload, AOT during release ensures performance
- Strong typing: Static type checking reduces runtime errors
- Null safety: Non-nullable by default, avoiding NullPointerException
- Async support: async/await + Isolate concurrency
Dart Language Basics
Variables and Types
// Type inference
var name = 'Flutter'; // String
var age = 3; // int
var height = 1.8; // double
var isStudent = true; // bool
// Explicit types
String email = 'example@flutter.com';
int count = 100;
double price = 99.99;
// Null safety
String? nullableName; // Nullable type
String nonNullName = 'Must be assigned'; // Non-nullable type
// Null handling
print(nullableName?.length); // Conditional access
print(nullableName ?? 'Default value'); // Null-coalescing
print(nullableName!.length); // Force unwrap (dangerous)
Functions
// Basic function
int add(int a, int b) {
return a + b;
}
// Arrow function
int multiply(int a, int b) => a * b;
// Optional parameters
String greet(String name, {String? title}) {
if (title != null) {
return 'Hello, $title $name';
}
return 'Hello, $name';
}
// Default parameters
void printInfo(String name, {int age = 0, String city = 'Beijing'}) {
print('$name, $age years old, from $city');
}
// Usage
greet('John', title: 'Mr.');
printInfo('Jane', age: 25);
Classes and Objects
// Define class
class User {
final String name;
final int age;
String? email;
// Constructor
User({
required this.name,
required this.age,
this.email,
});
// Named constructor
User.anonymous() : name = 'Anonymous', age = 0;
// Method
String introduce() {
return 'I am $name, $age years old';
}
// Getter
bool get isAdult => age >= 18;
}
// Usage
var user = User(name: 'John', age: 25);
print(user.introduce());
print(user.isAdult);
Collections
// List
var fruits = ['Apple', 'Banana', 'Orange'];
fruits.add('Grape');
fruits.remove('Banana');
// Map
var scores = {
'Math': 95,
'English': 88,
'Chinese': 92,
};
print(scores['Math']);
// Set
var colors = {'Red', 'Green', 'Blue'};
colors.add('Yellow');
// Collection operations
var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map((n) => n * 2).toList();
var evens = numbers.where((n) => n % 2 == 0).toList();
var sum = numbers.reduce((a, b) => a + b);
Asynchronous Programming
// Future
Future<String> fetchData() async {
// Simulate network request
await Future.delayed(Duration(seconds: 2));
return 'Data loaded';
}
// Using async/await
void loadData() async {
print('Starting to load...');
var result = await fetchData();
print(result);
}
// Parallel async operations
void loadMultiple() async {
var results = await Future.wait([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
print(results);
}
// Stream
Stream<int> countStream() async* {
for (var i = 1; i <= 5; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
// Using Stream
void listenToStream() async {
await for (var value in countStream()) {
print(value);
}
}
Flutter Development Environment
Installation Steps
# 1. Download Flutter SDK
# Visit https://flutter.dev/docs/get-started/install
# 2. Extract and configure environment variables
# Windows
set PATH=%PATH%;C:\flutter\bin
# macOS/Linux
export PATH="$PATH:`pwd`/flutter/bin"
# 3. Run Flutter diagnostics
flutter doctor
# 4. Install necessary dependencies
flutter doctor --android-licenses
Flutter Doctor Output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.x.x)
[✓] Android toolchain
[✓] Chrome - develop for the web
[✓] Android Studio
[✓] VS Code
[✓] Connected device
Creating Your First Flutter Application
Project Initialization
# Create new project
flutter create my_first_app
# Enter project directory
cd my_first_app
# Run application
flutter run
Project Structure
my_first_app/
├── android/ # Android platform code
├── ios/ # iOS platform code
├── lib/ # Dart code (main development directory)
│ └── main.dart # Application entry point
├── test/ # Test code
├── web/ # Web platform code
├── pubspec.yaml # Project configuration file
└── README.md
Project Configuration
# pubspec.yaml
name: my_first_app
description: "My first Flutter application"
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
http: ^1.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
flutter:
uses-material-design: true
Practice: Counter Application
Complete Code
// lib/main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Code Analysis
1. Widget Tree Structure
MaterialApp
└── MyHomePage (StatefulWidget)
└── Scaffold
├── AppBar
│ └── Text
├── Body: Center
│ └── Column
│ ├── Text
│ └── Text
└── FloatingActionButton
2. StatefulWidget vs StatelessWidget
// StatelessWidget: immutable, no state
class MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Text('Hello');
}
}
// StatefulWidget: mutable, has state
class MyStatefulWidget extends StatefulWidget {
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int count = 0;
Widget build(BuildContext context) {
return Text('$count');
}
}
3. setState for State Updates
void _incrementCounter() {
setState(() {
_counter++;
});
// setState triggers rebuild, updating UI
}
Common Widgets
Layout Widgets
// Row: horizontal arrangement
Row(
children: [
Icon(Icons.star),
Icon(Icons.star),
Icon(Icons.star),
],
)
// Column: vertical arrangement
Column(
children: [
Text('Title'),
Text('Content'),
],
)
// Stack: stacking
Stack(
children: [
Image.network('url'),
Positioned(
bottom: 10,
left: 10,
child: Text('Image title'),
),
],
)
// Container: container
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
),
child: Center(child: Text('Hello')),
)
Interactive Widgets
// Button
ElevatedButton(
onPressed: () {
print('Button clicked');
},
child: Text('Click me'),
)
// Input field
TextField(
decoration: InputDecoration(
labelText: 'Username',
hintText: 'Please enter username',
),
onChanged: (value) {
print('Input: $value');
},
)
// List
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
onTap: () {
print('Clicked ${items[index]}');
},
);
},
)
Conclusion
Flutter is a powerful cross-platform development framework. Key takeaways:
- Dart language: Master basic syntax, async programming, null safety
- Widget system: Everything is a Widget, understand Widget tree construction
- State management: setState is the foundation, complex scenarios need Provider/Riverpod
- Development flow: Hot Reload significantly improves development efficiency
Flutter's learning curve is relatively gentle, especially for frontend developers with React/Vue experience. Once you master the Widget system and state management, you can quickly build beautiful cross-platform applications.
Next, you can dive deeper into Flutter's state management, routing, network requests, and other advanced topics.