一个欲儿的博客

一个欲儿的博客

Flutter入门基础
2025-11-24

一、知识储备

1. 引言

在各个原生操作系统中,对于如何构建用户界面都有其核心的概念和规范。例如,在 Android 开发中,这个核心概念是 View,iOS 中也有类似的 UIView。它们在本质上是相通的,但在具体实现和细节上有所不同。

基于这个背景,Flutter 框架引入了其最核心的基石概念——Widget

2. Widget:界面的“蓝图”

Flutter 的 Widget 与 Android 的 View 有相似之处,但存在根本性的区别。

  • Android View:通常由系统引擎管理。一个 View 被绘制后,如果需要修改内容(如改变文本),我们通过调用 invalidate() 等方法“标记”需要更新的区域,然后请求系统在下一帧进行重绘。这个“绘制”过程主要由系统控制。

  • Flutter Widget:其渲染引擎由 Flutter 自身实现。Widget 的核心思想是 “描述”界面,它本身并不是一个真正的显示对象,而更像一份不可变的配置蓝图。当界面的状态(如某个字段或属性)发生变化时,Flutter 会重建相关的 Widget 树(即重新生成界面描述),然后引擎会智能地将新的描述与旧的进行比较,并高效地只更新屏幕上实际发生变化的部分。

3. 性能考量:频繁重建会慢吗?

您可能会担心,属性一变就重建整个 Widget 树,性能会不会很差?答案是:通常不会。原因如下:

  1. Widget 是轻量的:重建 Widget 树(即执行 build 方法)的成本很低,因为它只是重新生成了配置信息。真正耗时的布局、绘制(由 Render Object 处理)环节,Flutter 框架做了大量优化,只会更新有差异的部分。

  2. 硬件性能足够:即使是当前几百元的入门级手机,其计算能力也足以流畅运行 Flutter 应用的这种响应式 UI 框架。

4. 响应式更新:与前端开发的奇妙关联

这种机制非常类似于前端开发中的 响应式编程 思想,比如您提到的 KuiKilly 组件库中的 @observable 装饰器。

  • 相似点:都是将数据状态与 UI 绑定。当被“观察”的数据发生变化时,依赖它的 UI 部分会自动重新渲染。

  • Flutter 的优势:在 KuiKilly 中,你可能需要重新运行项目才能看到变化。而 Flutter 提供了强大的热重载功能,代码修改后,界面几乎能立即更新,无需重启应用。这种开发体验确实与现代化前端开发非常相似,能极大提升开发效率。

5. 核心概念:StatelessWidget 与 StatefulWidget

那么,Widget 如何具体管理这种“变化”呢?这引出了 Flutter 中两种最基础的 Widget 类型。

StatelessWidget(无状态组件)

  • 适用场景:用于描述那些不依赖于自身内部状态变化的静态界面部分。它只依赖于父组件传入的、在构建时就确定不变的配置参数。

  • 类比:就像 Android 中一个只显示固定图标的 ImageView。因为这个图标在运行时不会改变,所以在 Flutter 中就用 StatelessWidget 来实现。

StatefulWidget(有状态组件)

  • 适用场景:用于描述那些需要根据数据变化(如网络请求结果)或用户交互(如点击按钮)而动态改变的界面部分。

  • 工作机制StatefulWidget 本身是不可变的,但它关联了一个独立的 State(状态)对象。当数据变化时,我们在 State 中调用 setState() 方法,这会通知 Flutter 框架:“状态变了,需要重建 UI!”。随后,Flutter 会重新执行 build 方法,用新的数据生成新的界面。

重要提示
无状态和有状态 Widget 在“每一帧都可能重建”这一点上行为是一致的。它们的根本区别在于,StatefulWidget 通过一个独立的 State 对象,实现了可变状态数据在多次重建间的持久化和恢复

一个简单的判断规则
如果一个 Widget 会因为用户交互或数据流而自己发生变化,它就应该是有状态的。但如果一个 Widget 的变化仅仅是因为它的父组件传递了新的数据给它,而父组件自身并不管理状态,那么这个 Widget 本身仍然可以是无状态的。

二、Flutter基础结构

1.MaterialApp 作为应用容器

2.Scaffold 作为页面骨架

3.StatefulWidget + State 管理状态

4.setState() 触发界面更新

5.浮动操作按钮触发状态变更

6.Center + Column/Text 布局显示内容

三、实操一个效果

1.需求描述

有个 Text Widget 没有相关联的状态信息,它只渲染传入构造器的信息,仅此而已。但是,假如你想要动态地改变它的text属性 "I Like Flutter",例如当你点击一个 FloatingActionButton 的时候,该怎么办呢?为了实现这个效果,将 Text Widget 嵌入一个 StatefulWidget 中,并在用户点击按钮的时候更新它。

2.代码如下

import 'package:flutter/material.dart';

void main() {
  runApp(const SampleApp());
}

class SampleApp extends StatelessWidget {
  const SampleApp({super.key});
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  const SampleAppPage({super.key});

  @override
  State<SampleAppPage> createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default placeholder text.
  String textToShow = 'I Like Flutter';

  void _updateText() {
    setState(() {
      // Update the text.
      textToShow = 'Flutter is Awesome!';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Sample App')),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: 'Update Text',
        child: const Icon(Icons.update),
      ),
    );
  }
}

3. 解释代码

runApp作为root容器
SampleApp里面只有不变的东西,比如title这种配置信息的话就是不变的,不会随业务逻辑发生改变,所以StatelessWidget继承的StatelessWidget类
SampleAppPage会有要随业务发生变化的属性,所以继承StatefulWidget类,并且申明一个属性state用来存放要变的具体属性

@override   State<SampleAppPage> createState() => _SampleAppPageState();

然后再看其他的地方
企业微信截图_3309ca4e-cf90-46c4-b60a-39c115632ed6.png


发表评论: