在移动开发领域,跨平台技术早已从 “可选” 变为 “必备”。Flutter 作为 Google 推出的跨平台 UI 框架,凭借高性能、跨端一致性、热重载三大核心优势,成为当下最热门的跨平台开发方案。本文将从零基础入门到实战开发,手把手带你掌握 Flutter 核心技能,所有示例代码可直接运行,图片均使用公开可访问链接,发布到 CSDN 后可直接显示。
一、为什么选择 Flutter?跨平台开发的 “最优解”
1. Flutter vs 传统跨平台框架
传统跨平台框架(如 React Native)采用 “JS 桥接原生” 模式,存在性能损耗和 UI 一致性问题;而 Flutter 直接基于 Skia 图形引擎自绘 UI,从底层解决了这些痛点:
| 特性 | Flutter | React Native |
|---|---|---|
| 渲染方式 | 自绘 UI(Skia 引擎) | 桥接原生控件 |
| 性能 | 接近原生(60fps) | 有桥接损耗 |
| 跨端一致性 | 完全一致 | 需适配不同平台原生控件 |
| 热重载 | 1 秒生效 | 需等待 JS 刷新 |
| 开发语言 | Dart(强类型) | JavaScript(弱类型) |
2. Flutter 核心优势(附效果图)
- 一次编码,多端运行:一套 Dart 代码可运行在 Android、iOS、Web、Windows、macOS、Linux;
- 热重载提效:修改代码后无需重启 App,1 秒内看到效果,开发效率提升数倍;
- 丰富的组件库:内置 Material Design(安卓风格)、Cupertino(iOS 风格)组件,快速搭建高颜值 UI;
- 原生级性能:编译为原生机器码,无 JS 桥接损耗,动画和交互流畅度媲美原生开发。
二、Flutter 环境搭建:3 步搞定(Windows/macOS 通用)
1. 前置准备
- 操作系统:Windows 10+/macOS 10.14+
- 开发工具:Android Studio(推荐)/VS Code
- 必备依赖:Git、JDK 11+(Android 开发需要)
2. 详细搭建步骤
步骤 1:下载 Flutter SDK
访问Flutter 官网下载稳定版 SDK,解压到无中文 / 空格的目录(如D:\flutter)。
步骤 2:配置环境变量
- Windows:在「系统环境变量 - Path」中添加
D:\flutter\bin和D:\flutter\bin\cache\dart-sdk\bin; - macOS:在
~/.zshrc(或~/.bash_profile)中添加:bash
运行
执行export PATH="$PATH:/Users/你的用户名/flutter/bin"source ~/.zshrc生效。
步骤 3:验证环境
打开终端 / 命令行,执行flutter doctor,出现绿色对勾即配置成功:
若提示 Android 许可证问题,执行
flutter doctor --android-licenses,按提示输入y同意所有许可证。
步骤 4:配置开发工具
在 Android Studio/VS Code 中安装「Flutter」和「Dart」插件,重启工具即可开始开发。
三、基础实战:Hello World 与 Flutter 布局核心
1. 创建第一个 Flutter 项目
- Android Studio 中选择「Start a new Flutter project」→「Flutter Application」;
- 填写项目名称(如
flutter_hello)、保存路径,等待项目初始化; - 核心文件说明:
lib/main.dart是 Flutter 应用的入口文件,所有代码逻辑均在此(或拆分到其他文件)。
2. 完整代码:带布局的 Hello World
dart
import 'package:flutter/material.dart';
// Flutter应用入口函数
void main() {
runApp(const MyApp());
}
// 根组件:无状态组件(StatelessWidget,UI不可变)
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 必须重写build方法,构建UI界面
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Hello World',
// 全局主题配置
theme: ThemeData(primarySwatch: Colors.blue),
// 首页组件
home: const HomePage(),
);
}
}
// 首页组件:有状态组件(StatefulWidget,可维护状态)
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
// Scaffold:页面脚手架,提供AppBar、body、底部导航等
return Scaffold(
appBar: AppBar(title: const Text('Flutter入门实战')),
// 页面主体:居中布局+垂直排列
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center, // 垂直居中
children: [
// Flutter图标
Icon(
Icons.flutter_dash,
size: 100,
color: Colors.blue,
),
SizedBox(height: 20), // 间距组件
// 文本组件
Text(
'Hello Flutter!',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}
3. 运行效果(可直接显示)
4. 核心知识点解析
- Widget(组件):Flutter 中 “一切皆是组件”,分为
StatelessWidget(无状态,UI 固定)和StatefulWidget(有状态,UI 可随数据变化); - 布局组件:
Center(居中)、Column(垂直布局)、Row(水平布局)、SizedBox(间距 / 固定大小)是最常用的布局组件; - build 方法:每个组件必须重写
build方法,Flutter 通过该方法构建 UI 树,状态变化时会重新执行build更新 UI。
四、进阶实战 1:状态管理 —— 实现计数器功能
1. 功能需求
点击悬浮按钮,数字实时递增,核心演示 Flutter 的 “状态管理” 和 “事件处理”,这是 Flutter 开发的核心基础。
2. 完整代码(修改lib/main.dart)
dart
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计数器',
theme: ThemeData(primarySwatch: Colors.red),
home: const CounterPage(),
);
}
}
// 计数器页面(有状态组件)
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _count = 0; // 计数器状态(私有变量)
// 点击事件:更新计数器
void _incrementCount() {
// setState:通知Flutter状态变更,触发UI重建
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter计数器Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'你点击的次数:',
style: TextStyle(fontSize: 18),
),
// 显示计数器数值
Text(
'$_count', // Dart字符串插值语法
style: const TextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
],
),
),
// 悬浮按钮:绑定点击事件
floatingActionButton: FloatingActionButton(
onPressed: _incrementCount, // 事件绑定
tooltip: '增加', // 长按提示
child: const Icon(Icons.add),
),
);
}
}
3. 运行效果(动态 GIF,可直接显示
)
4. 核心知识点解析
- 状态管理:
setState是最基础的状态管理方式,调用后 Flutter 会重新执行build方法,更新依赖该状态的 UI; - 事件处理:通过
onPressed绑定按钮点击事件,类似前端的onclick; - Dart 语法:
_count以_开头表示私有变量,仅当前类可访问;'$_count'是字符串插值,快速拼接变量。
五、进阶实战 2:网络请求与列表渲染
1. 功能需求
调用公开 API(JSONPlaceholder)获取用户列表,渲染到页面中,演示 Flutter 网络请求、JSON 解析、列表优化渲染。
2. 步骤 1:添加网络权限(Android)
在android/app/src/main/AndroidManifest.xml中添加:
xml
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
3. 步骤 2:添加依赖(pubspec.yaml)
yaml
dependencies:
flutter:
sdk: flutter
http: ^1.1.0 # 网络请求库
执行flutter pub get安装依赖。
4. 完整代码
dart
import 'package:flutter/material.dart';
import 'dart:convert'; // JSON解析
import 'package:http/http.dart' as http; // 网络请求
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.green),
home: const UserListPage(),
);
}
}
// 用户数据模型(封装JSON解析)
class User {
final int id;
final String name;
final String email;
// 构造函数
User({required this.id, required this.name, required this.email});
// 工厂方法:从JSON转为User对象
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
email: json['email'],
);
}
}
// 用户列表页面
class UserListPage extends StatefulWidget {
const UserListPage({super.key});
@override
State<UserListPage> createState() => _UserListPageState();
}
class _UserListPageState extends State<UserListPage> {
List<User> _userList = []; // 用户列表数据
bool _isLoading = true; // 加载状态
// 初始化时加载数据
@override
void initState() {
super.initState();
_fetchUsers();
}
// 网络请求:获取用户列表
Future<void> _fetchUsers() async {
try {
// 发起GET请求
final response = await http.get(
Uri.parse('https://jsonplaceholder.typicode.com/users'),
);
// 状态码200表示请求成功
if (response.statusCode == 200) {
// 解析JSON数组
List<dynamic> jsonData = json.decode(response.body);
// 转换为User对象列表
setState(() {
_userList = jsonData.map((json) => User.fromJson(json)).toList();
_isLoading = false;
});
} else {
throw Exception('请求失败:${response.statusCode}');
}
} catch (e) {
setState(() => _isLoading = false);
// 弹出错误提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('加载失败:$e')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('用户列表')),
// 根据加载状态显示不同UI
body: _isLoading
? const Center(child: CircularProgressIndicator()) // 加载中
: ListView.builder(
// 高效列表渲染:仅渲染可见项
itemCount: _userList.length,
itemBuilder: (context, index) {
User user = _userList[index];
// 列表项
return ListTile(
leading: CircleAvatar(child: Text('${user.id}')), // 头像
title: Text(user.name), // 姓名
subtitle: Text(user.email), // 邮箱
trailing: const Icon(Icons.arrow_forward_ios),
onTap: () {
// 列表项点击事件
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('选中用户:${user.name}')),
);
},
);
},
),
);
}
}
5. 运行效果(可直接显示)
6. 核心知识点解析
- 网络请求:使用
http库发起异步请求,结合async/await处理异步逻辑; - JSON 解析:通过 “数据模型类 + 工厂方法” 封装 JSON 解析,避免直接操作 Map,提升代码可读性;
- 列表优化:
ListView.builder是高性能列表组件,仅渲染当前可见的列表项,适合长列表; - 异步处理:
Future+async/await是 Dart 处理异步的核心方式,替代回调地狱。
六、综合实战:TodoList 待办事项 App(完整业务场景)
1. 功能需求
实现一个简易的 TodoList:添加待办、删除待办、标记完成,覆盖 “状态管理 + 表单 + 列表 + 交互” 全流程。
2. 完整代码
dart
import 'package:flutter/material.dart';
void main() {
runApp(const TodoApp());
}
class TodoApp extends StatelessWidget {
const TodoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter TodoList',
theme: ThemeData(primarySwatch: Colors.orange),
home: const TodoListPage(),
);
}
}
// 待办事项模型
class Todo {
final String id;
final String content;
bool isCompleted;
Todo({
required this.id,
required this.content,
this.isCompleted = false,
});
}
// 待办列表页面
class TodoListPage extends StatefulWidget {
const TodoListPage({super.key});
@override
State<TodoListPage> createState() => _TodoListPageState();
}
class _TodoListPageState extends State<TodoListPage> {
final TextEditingController _controller = TextEditingController(); // 输入框控制器
List<Todo> _todoList = []; // 待办列表
// 添加待办
void _addTodo() {
String content = _controller.text.trim();
if (content.isEmpty) return; // 空内容不添加
setState(() {
_todoList.add(Todo(
id: DateTime.now().microsecondsSinceEpoch.toString(), // 唯一ID
content: content,
));
_controller.clear(); // 清空输入框
});
}
// 切换待办完成状态
void _toggleTodo(String id) {
setState(() {
_todoList = _todoList.map((todo) {
if (todo.id == id) {
return Todo(
id: todo.id,
content: todo.content,
isCompleted: !todo.isCompleted,
);
}
return todo;
}).toList();
});
}
// 删除待办
void _deleteTodo(String id) {
setState(() {
_todoList.removeWhere((todo) => todo.id == id);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter TodoList')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// 输入框+添加按钮
Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: const InputDecoration(
hintText: '请输入待办事项...',
border: OutlineInputBorder(),
),
onSubmitted: (value) => _addTodo(), // 回车添加
),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: _addTodo,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
),
child: const Text('添加'),
),
],
),
const SizedBox(height: 20),
// 待办列表
Expanded(
child: _todoList.isEmpty
? const Center(
child: Text(
'暂无待办事项,添加一个吧!',
style: TextStyle(color: Colors.grey, fontSize: 16),
),
)
: ListView.builder(
itemCount: _todoList.length,
itemBuilder: (context, index) {
Todo todo = _todoList[index];
return ListTile(
leading: Checkbox(
value: todo.isCompleted,
onChanged: (value) => _toggleTodo(todo.id),
),
title: Text(
todo.content,
style: TextStyle(
decoration: todo.isCompleted
? TextDecoration.lineThrough
: TextDecoration.none,
color: todo.isCompleted ? Colors.grey : Colors.black,
),
),
trailing: IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () => _deleteTodo(todo.id),
),
);
},
),
),
],
),
),
);
}
}
3. 运行效果(动态 GIF,可直接显示)
4. 核心知识点解析
- 文本控制器:
TextEditingController用于控制输入框内容,实现 “输入 - 清空” 逻辑; - 列表操作:通过
add/removeWhere/map实现待办的增删改; - 交互控件:
Checkbox(复选框)、TextField(输入框)、IconButton(图标按钮)是表单类 App 的核心控件; - UI 状态联动:通过
TextDecoration.lineThrough实现 “完成待办划横线” 的 UI 联动效果。
七、CSDN 发布小贴士(必看!)
1. 图片显示保障
- 本文所有图片均使用
picsum.photos(静态图)、giphy.com(动态 GIF)的公开链接,发布后可直接显示; - 若替换为自己的截图 / GIF,优先使用 CSDN 自有图床:编辑文章时点击「图片」→「本地上传」,自动生成稳定链接(避免外部防盗链);
- GIF 大小控制在 5MB 以内,可使用 ScreenToGif(Windows)/Kap(Mac)压缩后上传。
2. 代码格式优化
- 代码块添加语言标识(如
```dart),CSDN 会自动高亮语法; - 代码添加详细注释,提升可读性;
- 关键代码行用注释标注(如
// 核心:状态更新)。
3. 排版技巧
- 标题层级清晰(
##/###),重点内容用粗体标注; - 代码案例分步骤讲解,避免大段代码堆砌;
- 结尾添加 “总结”“学习方向”,提升文章价值。
总结
- Flutter 的核心优势是自绘 UI、跨端一致、高性能,是跨平台开发的首选框架;
- Flutter 开发的核心是Widget 组件和状态管理,
setState是最基础的状态管理方式; - 实际开发中需掌握网络请求、JSON 解析、列表优化三大核心技能,覆盖 80% 的业务场景;
- CSDN 发布文章时,优先使用自有图床上传图片,保证图片正常显示,代码格式规范提升阅读体验。
本文所有代码均可直接复制运行,建议你动手修改 TodoList 的样式(如添加分类、修改颜色),或扩展功能(如本地存储),在实践中加深理解。如果对你有帮助,欢迎点赞、收藏、转发!
380

被折叠的 条评论
为什么被折叠?



