Flutter 环境搭建、常用指令、开发细节

729 阅读6分钟

一、环境搭建

  • Flutter 插件和包管理平台

  • Flutter 环境安装,官方中文文档,按着官方的来就够了,没啥难度。安卓模拟器可以使用 Android Studio 自带的也可以第三方的,例如:Genymotion

  • 配置环境变量,能全局使用 flutter 指令:

    • Mac:找到存放 Flutter 的文件夹里面的 bin 目录,复制全地址,添加到环境配置文件即可:

      $ open ~/.zshrc   # 如果使用的是 Zsh
      $ open ~/.bash_profile  # 如果使用的是 Bash
      
      或
      
      $ vim ~/.zshrc   # 如果使用的是 Zsh
      $ vim ~/.bash_profile  # 如果使用的是 Bash
      

      填入环境配置文件内容,PUB_HOSTED_URLFLUTTER_STORAGE_BASE_URL 也带上了:

      export PATH="$PATH:/Users/dengzemiao/Desktop/Project/flutter/Flutter/flutter/bin"
      export PUB_HOSTED_URL=https://pub.flutter-io.cn
      export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
      

      填入内容后,保存执行命令使配置生效:

      $ source ~/.zshrc   # 如果使用的是 Zsh
      $ source ~/.bash_profile  # 如果使用的是 Bash
      
    • Win:跟 Mac 同理,找到存放 Flutter 的文件夹里面的 bin 目录,例如:C:\flutter\bin

      1、打开环境变量设置

      • 按下 Win + S 键,搜索并打开 环境变量Edit the system environment variables
      • 在弹出的 系统属性 窗口中,点击 环境变量 (Environment Variables)

      2、添加 FlutterPATH

      • 系统变量 下,找到并选择 Path,点击 编辑 (Edit)

      • 点击 新建 (New) ,添加 Flutterbin 目录路径,例如:C:\flutter\bin

      3、点击 确定 (OK) 保存。

      4、PUB_HOSTED_URLFLUTTER_STORAGE_BASE_URL 也需要配置,文档中有。

二、常用命令

公共

# 列出 Flutter 支持的工具链
$ flutter --version

# 检查 Flutter 安装环境
$ flutter doctor

# 创建项目,VSCode 安装方式可以使用快捷键创建,一样的
$ flutter create project_name

# 创建项目,并初始化包名与项目名称
$ flutter create --org com.example project_name

# 设备列表
$ flutter devices

# 运行并选择设备
$ flutter run

# 运行到指定设备
$ flutter run -d <device_id>

# 清理构建缓存
$ flutter clean

# 安装依赖包
$ flutter pub get

# 移除指定依赖包
$ flutter pub remove http

# 升级依赖包
$ flutter pub upgrade

# 升级指定依赖包
$ flutter pub upgrade http

Android

# 构建 APK 文件(Android)默认 
# 所有构建出的 apk 包位于 build/app/outputs/flutter-apk/ 下
$ flutter build apk

# 打包调试版(开发测试用,包含调试信息)
$ flutter build apk --debug

# 打包发布版(正式上线用,优化代码和资源):
$ flutter build apk --release

# 生成分层 APK(适配不同 CPU 架构)
# 这会生成不同架构的 APK(如 armeabi-v7a、arm64-v8a),同样位于 build/app/outputs/flutter-apk/ 下
$ flutter build apk --split-per-abi

iOS(需 macOS 环境)

# 打开 ios 模拟器,它只能启动 macOS 自带的 Xcode iOS 模拟器
# 如果调用报错,就用 xcode 启动出来模拟器
$ open -a Simulator

$ 关闭 iOS 模拟器
$ killall Simulator

# 如果需要启动特定设备,可以使用 xcrun simctl 命令,或者使用 Xcode 进行切换启动对应模拟器
$ xcrun simctl boot "iPhone 14"
$ open -a Simulator

# 构建 APK 文件(Android)默认 
$ flutter build ios

# 打包调试版(开发测试用,包含调试信息)
$ flutter build ios --debug

# 打包发布版(正式上线用,优化代码和资源):
$ flutter build ios --release

依赖包管理(pub.dev)

# dependencies 中列出的包是应用程序运行时必需的,也就是说,这些依赖是项目在生产环境中执行时所需要的。
# dev_dependencies 中列出的包是仅在开发过程中需要的。这些包在生产环境中并不会被包含在内。它们用于开发、构建、测试和调试。

# 添加依赖包最新版本,默认都是添加到 dependencies
$ flutter pub add http

# 添加依赖包指定版本
$ flutter pub add http:1.0.0

# 添加依赖包到 dev_dependencies
$ flutter pub add --dev http

# 按照 pubspec.yaml 配置重新更新一遍本地插件,初始化、手动删除、手动添加都可以执行
# 同前端 npm install 一个意思
$ flutter pub get

# 更新所有插件
$ flutter pub upgrade

# 更新指定插件
$ flutter pub upgrade http

# 移除指定插件
$ flutter pub remove http

三、创建项目

  • 博主选用的是 VSCode 安装方式,安装完成后,按照文档创建一个测试项目,并运行到模拟器或真机。

    • 创建方式1:使用 Command + Shift + PCtrl + Shift + P,在弹出面板中输入 Flutter 选择 New Project 创建项目,这种会自动安装依赖。

    • 创建方式2:使用 $ flutter create project_name 创建项目,这种不会自动安装依赖,需要执行 $ flutter pub get 安装一下依赖,否则会报错: # Target of URI doesn‘t exist ‘package:flutter/material.dart‘ 之类的。

      安装依赖后,可以重启下项目,这样会在 VSCode 上避免语法补全功能遇到问题。

  • 项目结构图:

    代码开发在 lib 目录中完成,内部结构自行决定即可。

    my_flutter_project/
    ├── android/
    │   ├── app/                         # 存放 Android 构建相关的文件
    │   │   ├── build.gradle             # Android 构建配置
    │   │   └── src/
    │   │       └── main/
    │   │           ├── AndroidManifest.xml  # Android 配置文件
    │   │           ├── java/              # Java 或 Kotlin 代码
    │   │           └── res/               # Android 资源文件
    │   └── build.gradle                  # Android 项目配置
    ├── ios/
    │   ├── Runner/                       # 存放 iOS 构建相关的文件
    │   │   ├── AppDelegate.swift         # iOS 的入口文件
    │   │   ├── Info.plist                # iOS 配置文件
    │   │   ├── Runner.xcodeproj          # Xcode 项目文件
    │   └── Flutter/                      # 存放 Flutter 生成的 iOS 框架
    ├── lib/                              # 主要的 Dart 代码
    │   ├── main.dart                     # 应用的入口文件
    │   ├── app.dart                      # 应用的主逻辑(可选)
    │   ├── pages/                        # 存放页面的文件夹
    │   │   ├── home_page.dart            # 主页
    │   │   └── settings_page.dart        # 设置页
    │   ├── widgets/                      # 存放自定义组件的文件夹
    │   │   ├── custom_button.dart        # 自定义按钮组件
    │   │   └── app_bar.dart              # 自定义应用栏组件
    │   └── models/                       # 存放数据模型的文件夹
    │       └── user_model.dart           # 用户数据模型
    ├── assets/                            # 存放静态资源(图片、字体等)
    │   ├── images/                       # 存放图片
    │   │   ├── logo.png                  # 项目 logo
    │   │   └── background.jpg            # 背景图片
    │   ├── fonts/                        # 存放字体文件
    │   │   └── custom_font.ttf           # 自定义字体
    │   └── data/                         # 存放其他数据文件
    │       └── sample_data.json          # JSON 数据文件
    ├── build/                             # 存放构建生成的临时文件
    │   └── app/                           # 存放应用构建输出
    │       └── outputs/
    ├── test/                              # 存放测试代码
    │   └── widget_test.dart               # 测试 Flutter 小部件的代码
    ├── .gitignore                         # Git 忽略文件配置
    ├── .metadata                          # Flutter 项目的元数据文件
    ├── .flutter-plugins                   # 存放 Flutter 插件的配置信息
    ├── pubspec.yaml                       # Flutter 项目的配置文件,定义依赖项、版本等
    ├── pubspec.lock                       # 依赖的锁定文件,记录每个依赖的具体版本
    ├── analysis_options.yaml             # Dart 和 Flutter 的分析配置文件
    ├── base_project.iml                  # IntelliJ IDEA 或 Android Studio 项目的配置文件
    └── README.md                          # 项目的说明文件
    
  • Flutter 运行项目后,按 r 则可以支持热更新,还有其他指令:

    Flutter run key commands.
    r Hot reload. 🔥🔥🔥
    R Hot restart.
    h List all available interactive commands.
    d Detach (terminate "flutter run" but leave application running).
    c Clear the screen
    q Quit (terminate the application on the device).
    
  • 文件导入方式

    my_project/
        ├── lib/
            ├── src/
                ├── screens/
                    ├── home_screen.dart
                ├── models/
                    ├── user.dart
            ├── main.dart
    
    • 相对路径导入:

      import 'src/screens/home_screen.dart'; // 相对路径,从 lib 目录开始
      
    • 包式导入:

      import 'package:my_project/src/screens/home_screen.dart';
      
    • 总结:

      • 【推荐】使用包式导入:如果项目较大或需要清晰的模块化,包式导入(package:)是最推荐的方式。

      • 小型项目或简单项目使用相对路径导入:对于文件结构简单的项目,使用相对路径也非常便捷。

      • 总体来说,包式导入 更符合 FlutterDart 官方推荐的最佳实践,尤其是在大型项目中。

  • Flutter 默认可使用的 Icon(Icons.xxx)Flutter 默认提供的图标库中的一部分,属于 Material Icons,已经内置在 Flutter 框架中。无需额外安装任何库,就可以直接使用这些图标, 所有图标预览地址:material.io/resources/i…

  • 其他组件文档

  • 运行别人的项目,安装依赖:

    # 如果没事没用,才需要加上这行,优先尝试下面两个即可
    $ flutter pub cache repair
    
    # 先清空
    $ flutter clean
    
    # 再拉取
    $ flutter pub get
    
  • 素材文件夹配置

    素材文件夹 assets 一般都是在项目根目录创建,使用就如下:

    Image.asset(assets/images/tabbar_normal_1.png, width: 24.0, height: 24.0)
    

    如果直接这么使用会报错找不到路径,还需要在 pubspec.yaml 申明一下路径,这样就可以在项目内任意地方直接使用 assets/images/ 作为素材文件路径访问到准确的素材:

    flutter:
      assets:
        - assets/images/
    

四、插件依赖安装管理

1、查找插件

需要查找想要使用的插件。Flutter 的插件可以通过 pub.dev 查找和下载。这个网站提供了大量的 Flutter 插件,涵盖了 UI网络请求数据库等各个方面。

2、添加插件

  • 方式一:通过指令添加

    # 添加最新版本
    $ flutter pub add http
    
    # 添加指定版本
    $ flutter pub add http:1.0.0
    
  • 方式二

    Flutter 项目中,每个项目都有一个 pubspec.yaml 文件,这个文件管理了项目的依赖包。只需要将第三方插件的依赖添加到 dependencies 部分。

    例如:安装 http 插件来进行网络请求,插件的名字是 http,可以按照以下方式修改 pubspec.yaml 文件:

    dependencies:
      flutter:
        sdk: flutter
      http: ^0.13.3  # 添加你需要的插件版本号,或者直接使用最新的版本
    

    在这里,http 是插件的名字,^0.13.3 是插件的版本号。可以在 pub.dev 查找插件的最新版本。

    修改 pubspec.yaml 后,运行以下命令来安装插件:

    $ flutter pub get
    

    这个命令会下载并安装所有的依赖,包括刚刚添加的插件。

3、在代码中导入插件

安装插件后,可以在代码中使用该插件。在 Dart 文件中,使用 import 语句来导入插件。

例如,要使用 http 插件,需要在代码中导入它:

import 'package:http/http.dart' as http;

4、使用插件

一旦插件被成功导入,就可以根据插件文档提供的 API 来使用它。以下是一个使用 http 插件发送 GET 请求的简单示例:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('HTTP Request Example')),
        body: Center(child: ElevatedButton(
          onPressed: () {
            fetchData();
          },
          child: Text('Fetch Data'),
        )),
      ),
    );
  }

  // 使用 http 插件发送网络请求
  void fetchData() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    if (response.statusCode == 200) {
      print('Data fetched successfully: ${response.body}');
    } else {
      print('Failed to load data');
    }
  }
}

5、使用平台特定插件(可选)

如果插件需要在 AndroidiOS 上进行特定的设置(例如配置原生代码),需要按照插件文档中的说明进行平台配置。例如,某些插件可能需要在 AndroidiOS 项目中的原生配置文件中做一些修改。

6、更新插件

如果插件有更新,可以使用以下命令来更新依赖:

# 更新所有插件
$ flutter pub upgrade

# 更新指定插件
$ flutter pub upgrade http

这会检查 pubspec.yaml 中的依赖,并将它们更新到可用的最新版本。

7、移除插件

  • 方式一

    $ flutter pub remove http
    
  • 方式二

    如果不再需要某个插件,可以将其从 pubspec.yaml 文件中移除,并运行:

    $ flutter pub get
    

    来同步更新项目依赖。

五、const 使用注意

  • 使用 const 时,确保该对象所有的成员也是常量,并且该对象的所有状态都不可修改。否则,Flutter 编译器会报错,无法将该对象标记为常量。

  • 现在官方自带很多案例,或者代码补全也使用了 const 但是一定要确保内容是不可变的才使用,否则父元素使用了 const 子元素使用可变对象都会报错。

六、全局对象(例:公共日志对象)

  • 其他的全局对象使用也是同理。

  • 在输出日志的时候,使用系统自带的 print 也没问题,但是会有警告提示,会推荐使用 logger 第三方日志库。

  • 安装 logger

    $ flutter pub add logger
    
  • 创建一个公共文件,专门存放一下全局对象,方便使用,例如:utils/globals.dart,然后在这个文件内写入:

    import 'package:logger/logger.dart';
    
    // 日志对象
    final Logger logger = Logger();
    

    补充:

    • final:只能赋值一次,赋值可以在运行时确定。
    • const:编译时常量,值不可变,适用于所有类型的常量。
    • static:声明静态成员,类的所有实例共享该成员。
    • var:声明变量,类型由初始值推断,变量可以重新赋值。
    • late:用于延迟初始化非 null 变量,确保变量在使用前初始化。
    • dynamic:类型不确定的变量,可以在运行时动态赋值。
  • 在需要使用全局对象 logger 的使用都引入一遍

    // 使用页面导入
    // import '../utils/public.dart';
    // 推荐按下面这么写,这样就不需要管层级
    import 'package:base_project/utils/public.dart';
    
    // 直接使用对象
    logger.i("Info log");
    logger.e("Error log", error: 'Test Error');
    logger.d("Debug log");
    logger.w("Warning log");
    logger.t("Trace log");
    logger.f("What a fatal log");
    

七、打包

  • 待更新...