Flutter 入门概览 1-Flutter 篇

Linshiyi
2026-04-28 20:39:38Flutter

本系列文章共有三篇,计划分别从 Flutter、Dart、工具三个方面介绍,快速形成对 Flutter 开发的一个综合概念。

本文主要介绍 Flutter 相关知识。

Flutter 语言使用 Dart,开发 IDE 使用 VSCode、Android Studio 或 IntelliJ IDEA,个人推荐使用 VSCode。

Flutter 概览

Flutter 是由 Google 开发的开源移动应用开发框架,用于快速构建高性能、高保真度的跨平台移动应用。Flutter 支持同一套代码在 iOS、Android、Web、桌面应用等多个平台上运行,使用自带的 Skia 图形引擎,可以直接绘制 UI 组件,这使得 Flutter 应用在性能方面表现出色,滚动流畅,响应迅速(目前正在使用 Impeller 替换 Skia)。

Flutter 架构

看一眼有个印象即可。

参考资料

三棵树

Flutter 的渲染机制由三棵树组成:Widget Tree、Element Tree、Render Tree(渲染树)。

  1. 所有 Widget 组成 Widget Tree。
  2. 通过调用 Widget 的createElement()方法,创建 Element Tree,Wdiget Tree 与 Element Tree 是一一对应的。
  3. 每个 Element 调用 createRenderObject()形成 Render Tree,Render Tree 负责渲染,注意 Render Tree 与 Elemeng Tree 并不是一一对应的,而是为最后渲染做准备。

Widget

在 Flutter 中,widget 是一个非常重要的概念,是描述 UI 的基本元素。可以用 iOS 中的 UIView 来类比理解 widget 的概念,但是 widget 并不是 UIView。widget 只是对布局的一种描述,最终还要经过三棵树生成 element 和 renderObject 才会被绘制到屏幕上,而 UIView 就是最终渲染的 view。

这里可以给出一个 widget 的定义:widget 是 Flutter 中描述一 UI 元素的配置信息,需要经过三棵树生成最终的 renderObject 才会被渲染到屏幕上。可以用 UIView 理解,但是 UIView 更像 renderObject。

在 Flutter 中,通过 widget 嵌套 widget 的方式来构建 UI 和进行事件处理,所以万物都是 Widget。Widget 的基类是Widget,是一个抽象类一般不会直接用。

在 flutter 中,widget 分为两类:有状态的 widget 和无状态的 widget,即StatefulWidgetStatelessWidget,两个都直接继承自Widget类。不需要改变的元素使用StatelessWidget,设定好后元素不会被改变;需要改变的元素需要使用 StatefulWidget,通过改变内部 state 来修改自身 UI,触发重新渲染。

  • StatelessWidget,无状态 widget,设定好后不能再修改。
  • StatefulWidget,有状态的 widget,内部会对应一个 State 类,通过修改 State 可以改变自身 widget,然后更新 UI。

参考:

StatelessWidget

StatelessWidget 是无状态组件,通过build方法来构建 UI。

  • build,通过 build 方法嵌套其他 widget 来构建 UI,在构建过程中会递归的构建其他嵌套的 widget。
  • contextbuild方法有一个context参数,它是BuildContext类的一个实例,表示当前 widget 在 widget 树中的上下文,每一个 widget 都会对应一个 context 对象(因为每一个 widget 都是 widget 树上的一个节点)。实际上,context是当前 widget 在 widget 树中位置中执行” 相关操作 “的一个句柄 (handle),比如它提供了从当前 widget 开始向上遍历 widget 树以及按照 widget 类型查找父级 widget 的方法。
// StatelessWidget 定义
abstract class StatelessWidget extends Widget {
  const StatelessWidget({ super.key });

  @override
  StatelessElement createElement() => StatelessElement(this);
  
  // 核心是 build 方法
  @protected
  Widget build(BuildContext context);
}

// 示例,Echo widget,核心是build方法构建UI
class Echo extends StatelessWidget  {
  const Echo({
    Key? key,  
    required this.text,
    this.backgroundColor = Colors.grey, //默认为灰色
  }):super(key:key);
    
  final String text;
  final Color backgroundColor;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: backgroundColor,
        child: Text(text),
      ),
    );
  }
}



// 在子树中获取父级widget的一个示例:
class ContextRoute extends StatelessWidget  {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Context测试"),
      ),
      body: Container(
        child: Builder(builder: (context) {
          // 在 widget 树中向上查找最近的父级`Scaffold`  widget 
          Scaffold scaffold = context.findAncestorWidgetOfExactType<Scaffold>();
          // 直接返回 AppBar的title, 此处实际上是Text("Context测试")
          return (scaffold.appBar as AppBar).title;
        }),
      ),
    );
  }
}



StatefulWidget

StatefulWidget 的核心就是有状态,可以修改重绘 UI。

  • StatefulWidget 重写了 createElement 方法,返回的是StatefulElementStatefulElement可能会多次调用createState()来创建对象。
  • createState(),创建状态,修改 UI 必须通过修改状态来实现,一个StatefulElement对应一个State实例。
abstract class StatefulWidget extends Widget {
  const StatefulWidget({ Key key }) : super(key: key);
    
  @override
  StatefulElement createElement() => StatefulElement(this);
    
  @protected
  State createState();
}


State

一个 StatefulWidget 类会对应一个 State 类,State 表示与其对应的 StatefulWidget 要维护的状态。

State 中的状态信息:

  1. 在 widget 构建时可以被同步读取。
  2. 在 widget 生命周期中可以被改变,当 State 被改变时,可以手动调用其setState()方法通知 Flutter 框架状态发生改变,Flutter 框架在收到消息后,会重新调用其build方法重新构建 widget 树,从而达到更新 UI 的目的。

State 中有两个常用的信息:

  1. widget,它表示与该 State 实例关联的 widget 实例,由 Flutter 框架动态设置。注意,这种关联并非永久的,因为在应用生命周期中,UI 树上的某一个节点的 widget 实例在重新构建时可能会变化,但 State 实例只会在第一次插入到树中时被创建,当在重新构建时,如果 widget 被修改了,Flutter 框架会动态设置 State. widget 为新的 widget 实例。
  2. context。StatefulWidget 对应的 BuildContext,作用同 StatelessWidget 的 BuildContext。

State 生命周期:

这块详细参考:State-Flutter 实战第二版

参考资料

布局

Debugger 输出

  • debugPrint
  • Print
  • log
// debugPrint
import 'package:flutter/foundation.dart';、
debugPrint('movieTitle: $movieTitle');

// log
import 'dart:developer';  //(auto import will do this even)
//example for api logging
log("${response?.statusCode} :  ${response?.request?.path}",
          name: "Response", error: response.data);



Flutter 命令

// 检测flutter配置,输出相关依赖的安装情况
flutter doctor

// flutter 工程安装依赖,注意针对flutter工程,需要使用flutter命令(dart pub get是针对dart工程)
flutter pub get


// flutter 工程添加依赖
flutter pub add css_colors

// flutter 移除依赖
flutter pub remove css_colors

// 运行flutter工程
flutter run

// Other
// 升级Flutter SDK
flutter upgrade

// 创建Flutter App
flutter create test_drive // 创建Flutter工程模板
flutter devices // 选择对应的平台
flutter run // 运行Flutter工程

// 后续注意使用 fvm flutter 代替 flutter
# Use
> fvm flutter {command}
# Instead of
> flutter {command}

// 后续使用 fvm dart 代替 dart
# Use
> fvm dart {command}
# Instead of
> dart {command}




创建 Flutter 工程

具体参考:开发体验初探

通过 VSCode 创建 Flutter App:

  • 打开 VSCode 命令窗口,输入 Flutter,选择Flutter: New Project
  • 通过命令行创建 :flutter create -t app

Flutter 工程结构目录

工程结构

创建工程后,默认会显示以下文件

.
├── .dart_tool    # 记录了一些dart工具库所在的位置和信息
├── .idea      # android studio 是基于idea开发的,.idea 记录了项目的一些文件的变更记录
├── android      # Android项目文件夹
├── build      # 编译或运行后产物
├── ios        # iOS项目文件夹
├── lib        # lib文件夹存放我们的dart语言代码
├── linux      # Linux项目目录
├── macos      # mac项目目录
├── test      # 测试代码
├── web        # web项目目录
├── windows      # win项目目录
├── .gitignore    # git忽略配置文件
├── .metadata    # 一个对当前workspace的配置记录
├── analysis_options.yaml      # flutter lint配置文件,定义代码静态分析相关的配置项和规则
├── flutter_application_1.iml    # 工程文件的本地路径配置,在Android Studio或IntelliJ下起作用
├── pubspec.lock          # 项目依赖的lock文件
├── pubspec.yaml          # 依赖配置文件,类似package.json文件
└── README.md             # README


其中比较关注以下几个文件夹:

  • lib,存放工程的核心代码
  • pubspec.yaml,依赖配置管理

另外,一般额外创建两个目录:assetsfonts,用于存放图片和字体,注意需要在pubspec.yaml文件中声明。

# 示例
# The following section is specific to Flutter.
flutter:

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/images/

  fonts:
    - family: Raleway
      fonts:
        - asset: fonts/Raleway-Regular.ttf
        - asset: fonts/Raleway-Italic.ttf
          style: italic
    - family: RobotoMono
      fonts:
        - asset: fonts/RobotoMono-Regular.ttf
        - asset: fonts/RobotoMono-Bold.ttf
          weight: 700


lib 目录结构

不要一直寻求最佳实践,最佳实践只是最小省力原则,要 go above and beyond。

lib 目录是存放了我们工程代码,结合前端工程,目前得出一个最佳目录结构。

lib
├── main.dart
├── api # 接口请求
├── components # 公共组件
├── l10n # 国际化,Flutter中使用 flutter_localizations 库作为国际化,因此叫l10n
├── router # 路由
├── store # 状态管理
├── models    # Json文件对应的Dart Model类会在此目录下
├── types # 公共类型定义
├── utils # 工具函数、通用方法、网络接口
└── pages # 页面


参考:

pubspec.yaml 文件

参考资料

常用三方库

功能类

工具类

  • mason,文件模板生成器,方便做脚手架用
  • melos,Flutter 的 Monorepo 管理工具
  • freezed,一个用于数据类 / 联合体 / 模式匹配 / 克隆的代码生成器

学习 Demo

FlutterUnit

FlutterUnit 是一个非常强大的 Flutter 学习利器,提供全面的 Flutter 学习指南,支持 iPhone/Andriod/Mac/PC 全平台,可以快速查看组件 API 说明和示例。可以说是学习 Flutter 的必备学习软件。

Flutter 源码中的可用的组件一共 350 个左右,纷繁复杂,也没有明确的分类标准 FlutterUnit 对大大小小,常用不常用的组件能收的尽量收录。并根据个人感觉进行评星 目前收录组件306个,每个都有至少一个演示展现和代码展示。

FlutterUnit 提供以下功能:

  • 300 + 组件的收录
  • 组件详情说明,提供组件的属性和说明演示
  • 可操作,操作交互类组件提供可操作性
  • 提供组件的关联切换

Material Design

是一种用户界面设计语言,开始被 Google 引入用于安卓的 UI 设计风格。现在提供一系列 UI 组件,Flutter 核心的 UI 库。

参考资料:

参考资料

📝 转载声明

评论加载中...