Flutter 基础详解

引用:
flutter常用的三方库
Flutter基础(二)--App结构和生命周期
Flutter 网络请求深度解析
Flutter 项目常用插件库推荐(2025 最新版)

image.png
  • dart:是一种面向对象语言,dart是flutter的程序开发语言。
  • main函数:是程序运行的入口函数
  • runApp函数:是渲染根widget树的函数
    一般情况下runApp函数会在main函数里执行

语言的主要特点是什么?

  • 面向对象:支持类和单继承
  • 强类型:但支持类型推断
  • 异步编程:内置 Future 和 Stream 支持
  • 空安全:支持非空类型检查
  • JIT 和 AOT:支持即时编译和提前编译

widget
widget在flutter里基本是一些UI组件
有两种类型的widget:
statefulWidget:会自己重新构建自己(可以改变状态,通过 setState() 触发重建)
statelessWidget:不可变,一旦创建就不能改变
布局Widget:Container、Row、Column、Stack等。
常用Widget:Text、Image、ListView、GridView等。

StatefulWidget:通过setState管理状态。
状态管理方案:Provider、Riverpod、Bloc、GetX等状态管理工具。

Flutter 中的生命周期
  • StatelessWidget:
    build()
  • StatefulWidget:
    创建/初始化:createState()、initState()
    依赖:didChangeDependencies()
    构建:build()「每次父Widget重新构建时都会调用此方法,setState 调用?」
    更新:didUpdateWidget()
    失活:deactivate() 「当应用从后台切换到前台时」
    清理:dispose() 「清理资源、取消订阅、关闭流等」
生命周期方法 调用时机 典型用途
createState StatefulWidget 创建时,框架会调用此方法创建 State 对象。 返回 State 实例。
initState State 对象被插入 Widget 树时仅调用一次 初始化数据、订阅 Stream、创建动画控制器、监听事件。
didChangeDependencies initState 之后立即调用;当该 State 对象的依赖发生变化时(如 InheritedWidget 更新)。 依赖 InheritedWidget 的场景,比如主题、语言变化时的响应。
build 每次构建 Widget 树时都会调用(可能被频繁调用)。 必须返回一个 Widget 树,不要在此执行耗时操作。
didUpdateWidget 父组件重建导致当前 Widget 的配置发生变化时。 响应父组件传下来的 widget 属性变化,如 oldWidget 比较。
setState 开发者手动调用,通知框架数据变化。 更新 UI 数据,触发 build 重新执行。
deactivate State 对象从 Widget 树中被移除时(可能被重新插入)。 清理与当前树位置相关的临时资源。
dispose State 对象永久从 Widget 树中移除时仅调用一次 取消订阅、停止动画、销毁控制器、释放资源(必须!)。
image.png


状态管理

Flutter 中有哪些状态管理方案?

基础方案:setState
中级方案:InheritedWidget、Provider
高级方案:Riverpod、BLC、Redux、MobX、GetX

Provider 的工作原理是什么?

Provider 是基于 InheritedWidget 的封装,它允许在 Widget 树中高效地共享数据。当数据变化时,只有依赖该数据的 Widget 会重建。

什么是 BLC 模式?

BLC (Business Logic Component) 是一种状态管理模式,它将业务逻辑与 UI 分离,使用 Stream 和 Sink 来处理数据流。


什么是 BuildContext?

BuildContext 是 Widget 在树中位置的句柄(上下文联系的桥梁),用于:

  • 查找父 Widget 或主题
  • 导航 (Navigator.of(context))
  • 显示对话框等


Hot Reload 和 Hot Restart 有什么区别吗?

Hot Reload比Hot Restart快
Hot Reload:[热重载],局部刷新,会编译我们文件里新加的代码并发送给dart虚拟机,dart会更新widgets来改变UI,会保留之前的state。
Hot Restart:[热重启] 重新启动整个应用。Hot Restart会重置所有的state回到初始值。


异步编程:理解Stream,掌握async和await。
包管理:学习如何使用pubspec.yaml管理依赖。
Stream
Stream 用来处理连续的异步操作,Stream 是一个抽象类,用于表示一序列异步数据的源。它是一种产生连续事件的方式,可以生成数据事件或者错误事件,以及流结束时的完成事件
Stream 分单订阅流和广播流。
网络状态的监控

Dart 中的 final 和 const 有什么区别?
  • const:编译时常量,必须在编译时就知道值
  • final:运行时常量,只能赋值一次

布局与样式

常见的布局 Widget 有哪些?

Container:通用容器,可设置 padding/margin/decoration
Row/Column:水平和垂直布局
Stack:重叠布局
ListView/GridView:滚动列表
Flex/Expanded:弹性布局

如何实现响应式布局?

使用 MediaQuery.of(context) 获取屏幕尺寸
使用 LayoutBuilder 获取约束条件
使用 Flexible 和 Expanded 弹性布局
使用百分比或弹性布局
使用 OrientationBuilder 处理横竖屏变化

什么是 Theme?

Theme 是 Flutter 中统一管理应用样式的方式,可以定义颜色、字体、按钮样式等,并在整个应用中保持一致。

路由与导航

如何在 Flutter 中实现导航?
'//导航到新页面'
Navigator.push(context, MaterialPageRoute(builder: (context) => NewPage()));
'//返回上一页'
Navigator.pop(context);
命名路由如何配置?
MaterialApp(
  routes: {
    '/': (context) => HomePage(),
    '/details': (context) => DetailsPage(),
  },
);


解释 Dart 中的异步编程

Dart 使用 Future 和 async/await 处理异步操作:

Future<String> fetchData() async {
  var response = await http.get('https://api.example.com/data');
  return response.body;
}


网络与存储

如何进行网络请求?使用 http 包:

var response = await http.get(Uri.parse('https://api.example.com/data'));

三方库:dio

Flutter 中的数据存储选项有哪些?

SharedPreferences:简单的键值对存储
SQLite:关系型数据库 (使用 sqflite 包)
Hive:轻量级 NoSQL 数据库
Firebase:云存储解决方案


性能优化

1. 如何优化 Flutter 应用性能?

使用 const Widget 减少重建
避免在 build 方法中进行耗时操作
使用 ListView.builder 处理长列表
减少 Widget 树的深度
使用性能分析工具 (Flutter DevTools)

2. 什么是 Widget 重建?如何避免不必要的重建?

Widget 重建是 Flutter 响应状态变化的机制。避免不必要重建的方法:
使用 const 构造函数
将不常变化的部分拆分为独立的 Widget
使用 Provider 等状态管理工具精确控制重建范围

常见的陷阱问题

Q1:setState 一定会触发 build 吗?
是的,setState 会标记当前 State 为 dirty,在下一帧强制重新执行 build

Q2:initState 中能否访问 context
可以访问,但不能进行依赖 InheritedWidget 的操作(因为 didChangeDependencies 还未调用)。如果需要,使用 WidgetsBinding.instance.addPostFrameCallback

Q3:dispose 中调用 setState 会怎样?
会报错:setState() called after dispose()。必须在调用前检查 mounted 属性。
if (mounted) {
setState(() {});
}

Q4:Hot Reload 会触发哪些生命周期?
只触发 build 和 didUpdateWidget(如果 widget 类型变化),不会触发 initState 和 dispose。

场景 正确做法
启动网络请求 initState 中异步发起,在 dispose 中取消。
监听滚动、主题变化 initState 订阅,在 dispose 取消。
动画控制器 initState 创建,在 dispose 销毁。
页面可见性(前后台) 使用 WidgetsBindingObserver 监听。
页面跳转时的资源清理 使用 RouteAware 监听路由生命周期。
initState 类似 iOS中的 Viewdidload?
特性 Flutter initState iOS viewDidLoad
调用时机 State 对象被插入 Widget 树时(仅一次) 视图控制器加载视图完成后(仅一次)
核心用途 初始化数据、配置监听、准备资源 初始化数据、配置 UI、准备资源
视图/UI 状态 此时 context 可用,但 UI 尚未构建完成 此时 view 已加载,但尚未显示到屏幕
典型操作 启动网络请求、添加监听、创建动画控制器 启动网络请求、添加通知、设置按钮点击事件
视图重建时 ❌ 重建时不调用(如主题切换、旋转屏幕) ✅ 重新调用(如内存警告后重建)
UI 状态 ❌ UI 尚未构建 ✅ UI 已经加载完成
能操作 UI 吗 不能直接操作 UI 组件(因为还没创建) 可以操作 UI 组件(如设置按钮文字)
对象分配 createState init
初始化和资源配置 initState viewDidLoad
依赖准备就绪 didChangeDependencies viewWillAppear

更准确的对应关系:

  • initStateinit 的一部分 + viewDidLoad:用于初始化数据、配置资源,但不能操作 UI。
  • didChangeDependenciesviewWillAppear:此时依赖已就绪,可以安全访问主题、Provider 等。
  • buildviewDidLayoutSubviews + 绘制:构建实际界面。

代码对比

// Flutter
@override
void initState() {
  super.initState();
  _loadData();           // 启动网络请求
  _addListener();        // 添加监听
  _initController();     // 初始化控制器
}
// iOS
override func viewDidLoad() {
    super.viewDidLoad()
    loadData()            // 启动网络请求
    addNotification()     // 添加通知
    setupUI()             // 初始化 UI 组件
}

Flutter 应用如何打包发布?

'//Android:'
flutter build appbundle
或
flutter build apk

//'iOS'
flutter build ios
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容