【Flutter入门】1. 从零开始的flutter跨平台开发之旅(概述、环境搭建、第一个Flutter应用)

前言

随着移动互联网的发展,跨平台开发已经成为一个不可忽视的技术方向。本文将带领读者从零开始学习 Flutter,循序渐进地掌握这个强大的跨平台开发框架。截至 2024 年 12 月,Flutter 已经发展到了 3.27 版本。在学习和使用的过程中,我发现国内现在网上可以找到的 Flutter 相关文章教程等并不多,且很多都是比较过时的。因此,我计划从 2025 年开始,分享自己平时做的笔记以及工作上积累的经验,希望能对正在学习或使用 Flutter 的同学有所帮助。同时,我也希望通过写作来磨练自己的技术。由于技术写作经验有限,文中可能存在逻辑表达不清、字词错误、代码错误或格式错误等问题,欢迎读者在评论区或私信中指出,以便及时修正优化,非常感谢!

Flutter 概述

什么是 Flutter?

Flutter 是 Google 推出的一个开源 UI 工具包,它彻底改变了我们对跨平台开发的认知。不同于传统的跨平台框架,Flutter 采用了自绘引擎 Skia 图形引擎,不依赖原生控件,这使得它可以完全控制渲染流程,保证多平台 UI 一致性,并提供更好的动画性能表现。此外,Flutter 支持 AOT(Ahead Of Time)编译,直接编译成原生代码,从而实现启动速度快、运行时性能好、内存占用小等优点。同时,Flutter 还支持 iOS、Android、Web、Windows、macOS 和 Linux 等多个平台,并提供了亚秒级的热重载功能,大大提升了开发效率。

AOT 与 JIT 编译

Flutter 根据不同场景使用两种编译模式:

  • AOT (Ahead Of Time) 编译:在应用发布前将 Dart 代码预编译为本地机器码,主要用于 Release 模式下的生产环境发布。这种方式能保证运行性能好、无需运行时编译、启动速度快、内存占用小。
  • JIT (Just In Time) 编译:在运行时动态将 Dart 代码编译为机器码,主要用于 Debug 模式下的开发环境。它支持热重载(Hot Reload),方便调试和提高开发效率。

Flutter 巧妙地结合了这两种编译模式的优势:开发时使用 JIT 提供流畅的开发体验;发布时使用 AOT 确保最佳性能。

为什么选择 Flutter?

在众多跨平台方案中,Flutter 具有显著优势,包括但不限于:

  • 开发效率:热重载支持、丰富的 Widget 库、完善的开发工具、统一的代码库。
  • 性能表现:接近原生的性能、流畅的 60fps 动画、优秀的渲染性能、较小的安装包体积。
  • 生态系统:活跃的开发者社区、丰富的第三方包、完善的文档支持、企业级支持。
  • 学习曲线:简洁的 Dart 语言、声明式 UI 设计、统一的开发模式、完整的学习资源。

Flutter vs 其他框架对比

特性 Flutter React Native Uni-app
渲染引擎 Skia 自绘引擎 JSCore + 原生桥接 V8/JSCore + WebView
渲染性能 接近原生 接近原生(部分损耗) 依赖浏览器
动画性能 60fps 稳定 部分场景丢帧 依赖设备性能
首屏加载 较快 需要 JS 引擎预热 需要 WebView 初始化
学习曲线 中等 较低(如熟悉 React) 较低
生态系统 快速成长 成熟稳定 完善
热重载 支持 支持 支持
包大小 较大 较小 中等
使用场景 全平台应用 移动端应用为主 偏向小程序
中文社区 一般 活跃 活跃
开发语言 Dart JavaScript JavaScript/Vue
上手难度 中等 较易 较易
调试工具 完善 完善 一般
跨平台性 优秀 良好 优秀

Flutter 应用场景

商业应用案例

  • 电商应用:阿里巴巴闲鱼,日活用户超过 3000 万,首屏加载时间小于 1 秒,开发效率提升 50%。
  • 社交应用:腾讯微视,视频播放性能接近原生,跨平台代码复用率大于 95%。
  • 金融应用:工商银行,交易模块性能达到原生水平,开发周期缩短 40%。
  • 生活服务:美团外卖,用户体验显著提升,研发效率大幅提高。

技术特点

  • 高性能渲染:自绘引擎保证性能,GPU 加速渲染,智能图层管理。
  • 快速开发迭代:毫秒级热重载,丰富的调试工具,自动化测试支持。
  • 优秀的动画支持:内置动画库,自定义动画支持,硬件加速。

适用场景

  • 需要快速开发的项目
  • 要求高性能的应用
  • 需要精美 UI 的产品
  • 跨平台一致性要求高的场景

开发环境搭建

系统要求

Windows 环境
  • 操作系统:Windows 10(推荐)或 Windows 7 SP1(最低要求),64 位操作系统(必需),开启 Hyper-V(Windows 10 Pro 以上版本)。
  • 硬件要求:CPU 需支持虚拟化技术,内存建议 8GB 以上(推荐 16GB),存储至少 10GB 可用空间。
  • 开发工具:Git for Windows 2.x, PowerShell 5.0+, Android Studio(推荐)或 VS Code, Android 开发环境(JDK 8 或更高版本,Android SDK Platform 29 或更高版本,Android SDK Command-line Tools)。
macOS 环境
  • 操作系统:macOS 10.15 (Catalina)或更高版本,建议使用最新版本以获得最佳性能。
  • 硬件要求:CPU:Intel 或 Apple Silicon,内存建议 16GB,存储至少 15GB 可用空间。
  • 开发工具:Xcode 13 或更高版本(iOS 开发必需),Android Studio 或 VS Code, CocoaPods(iOS 依赖管理),iOS 开发要求:Apple Developer 账号,iOS Simulator 或真机设备。

Flutter SDK 安装

Windows 详细步骤
# 创建开发目录
mkdir C:\src
cd C:\src

# 下载Flutter SDK
git clone https://github.com/flutter/flutter.git -b stable

# 添加Flutter到系统环境变量
setx PATH "%PATH%;C:\src\flutter\bin"

# 验证安装
flutter --version

# 检查环境变量是否生效
echo %PATH%

# 验证Flutter环境
flutter doctor -v

# 解决常见问题
flutter doctor --android-licenses

# 检查配置
flutter doctor
macOS 详细步骤
# 使用Homebrew安装
brew install --cask flutter

# 配置环境变量
# 添加到 ~/.zshrc 或 ~/.bash_profile
export PATH="$PATH:`pwd`/flutter/bin"

# iOS开发配置
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license

开发工具配置

Android Studio 配置
  • 插件安装:Flutter 插件, Dart 插件, Flutter Snippets, Flutter Enhancement Suite。

  • SDK 配置:Preferences > Languages & Frameworks > Flutter,设置 Flutter SDK 路径。

  • 模拟器配置:

    # 创建模拟器
    flutter emulators --create
    
    # 启动模拟器
    flutter emulators --launch <emulator_id>
    
VS Code 配置
  • 必要插件:Flutter, Dart, Flutter Widget Snippets, Awesome Flutter Snippets。
  • 配置设置:
    {
          
          
      "editor.formatOnSave": true,
      "editor.formatOnType": true,
      "dart.previewFlutterUiGuides": true
    }
    

Flutter 实战:Todo List 应用

项目概述

在学习了 Flutter 的核心概念后,我们将创建一个待办事项应用来实践这些知识,包括使用 StatelessWidget 和 StatefulWidget 感受 Widget 生命周期管理、应用状态管理、处理用户输入、实现数据持久化等功能。

创建项目

# 创建新项目
flutter create todo_list

# 进入项目目录
cd todo_list

# 运行项目
flutter run

项目结构解析

todo_list/
├── android/          # Android平台相关代码
├── ios/             # iOS平台相关代码
├── lib/             # Flutter源代码
│   └── main.dart    # 入口文件
├── test/            # 测试文件
└── pubspec.yaml     # 项目配置文件

基本代码解释

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: 'Todo List',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const TodoListPage(),
    );
  }
}

定义数据模型

// lib/models/todo_item.dart
class TodoItem {
    
    
  final String id;
  final String title;
  bool isCompleted;

  TodoItem({
    
    
    required this.id,
    required this.title,
    this.isCompleted = false,
  });

  // 用于JSON序列化
  Map<String, dynamic> toJson() => {
    
    
    'id': id,
    'title': title,
    'isCompleted': isCompleted,
  };

  // 从JSON创建实例
  factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
    id: json['id'],
    title: json['title'],
    isCompleted: json['isCompleted'],
  );
}

实现主页面

// lib/main.dart
import 'package:flutter/material.dart';
import 'package:todo_list/models/todo_item.dart';

/// 应用程序入口点
void main() {
    
    
  runApp(const MyApp());
}

/// 自定义无状态小部件,代表整个应用程序
class MyApp extends StatelessWidget {
    
    
  /// 构造函数,接收一个可选的key参数
  const MyApp({
    
    Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    
    
    // 返回MaterialApp小部件,配置应用程序的基本设置
    return MaterialApp(
      title: 'Todo List', // 设置应用程序标题
      theme: ThemeData(
        primarySwatch: Colors.blue, // 设置主题颜色
        useMaterial3: true, // 使用Material Design 3样式
      ),
      home: const TodoListPage(), // 设置主页面为TodoListPage
    );
  }
}

/// 自定义有状态小部件,表示待办事项列表页面
class TodoListPage extends StatefulWidget {
    
    
  /// 构造函数,接收一个可选的key参数
  const TodoListPage({
    
    Key? key}) : super(key: key);

  
  State<TodoListPage> createState() => _TodoListPageState();
}

/// 管理TodoListPage的状态
class _TodoListPageState extends State<TodoListPage> {
    
    
  // 存储所有待办事项的列表
  final List<TodoItem> _items = [];

  // 创建一个文本控制器,用于管理输入框中的文本
  final _textController = TextEditingController();

  /// 添加新的待办事项
  void _addTodoItem(String title) {
    
    
    if (title.isEmpty) return; // 如果标题为空,则不添加

    setState(() {
    
    
      // 添加新的待办事项到列表中
      _items.add(TodoItem(
        id: DateTime.now().toString(), // 使用当前时间戳作为唯一标识符
        title: title,
      ));
    });
    // 清空输入框
    _textController.clear();
  }

  /// 切换待办事项的完成状态
  void _toggleTodoItem(String id) {
    
    
    setState(() {
    
    
      // 查找并切换指定ID的待办事项的完成状态
      final item = _items.firstWhere((item) => item.id == id);
      item.isCompleted = !item.isCompleted;
    });
  }

  /// 移除待办事项
  void _removeTodoItem(String id) {
    
    
    setState(() {
    
    
      // 从列表中移除指定ID的待办事项
      _items.removeWhere((item) => item.id == id);
    });
  }

  
  Widget build(BuildContext context) {
    
    
    // 返回Scaffold小部件,包含应用栏和主体内容
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todo List'), // 设置应用栏标题
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _textController, // 绑定文本控制器
                    decoration: const InputDecoration(
                      hintText: '添加新的待办事项', // 设置输入框提示文本
                    ),
                  ),
                ),
                IconButton(
                  icon: const Icon(Icons.add), // 设置图标按钮的图标
                  onPressed: () => _addTodoItem(_textController.text), // 点击时调用添加方法
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _items.length, // 设置列表项数量
              itemBuilder: (context, index) {
    
    
                final item = _items[index];
                return ListTile(
                  leading: Checkbox(
                    value: item.isCompleted, // 设置复选框的状态
                    onChanged: (_) => _toggleTodoItem(item.id), // 状态变化时调用切换方法
                  ),
                  title: Text(
                    item.title, // 显示待办事项标题
                    style: TextStyle(
                      decoration: item.isCompleted
                          ? TextDecoration.lineThrough // 完成的事项加删除线
                          : null,
                    ),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.delete), // 设置删除按钮的图标
                    onPressed: () => _removeTodoItem(item.id), // 点击时调用移除方法
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  
  void dispose() {
    
    
    // 释放资源,确保没有内存泄漏
    _textController.dispose();
    super.dispose();
  }
}

注意事项

  • 代码规范:使用flutter_lints保持代码风格一致,遵循 Effective Dart 指南,合理使用注释和文档字符串,保持代码模块化和可测试性。
  • 性能优化:使用const构造函数避免不必要的重建,合理使用StatefulWidget,优化图片资源。
  • 调试技巧:使用 Flutter DevTools,推荐使用真机运行调试项目,利用性能分析工具,采用常见问题排查方法,制定日志管理策略。

参考资源

常见问题及解决方案

  • Android Studio 卡顿
    • 增加 Android Studio 内存:修改studio64.exe.vmoptions文件,增加内存至 4096m 或更多。
  • Flutter SDK 下载慢
    • 使用国内镜像:
      export PUB_HOSTED_URL=https://pub.flutter-io.cn
      export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
      
  • iOS 模拟器问题
    • 重置模拟器:
      xcrun simctl erase all
      
  • 依赖安装失败
    • pubspec.yaml中指定版本:
      dependencies:
        package_name: ^x.y.z
      

本篇文章到这就差不多啦~
如有疑问欢迎评论区讨论或者私信

猜你喜欢

转载自blog.csdn.net/xichen_knight/article/details/144754520
今日推荐