是什么
它是 Flutter SDK 提供的一个 Mixin;
作用是:当 Widget 离开屏幕(比如 Tab 页切换),可以让它的 State 不会被销毁,从而保持页面状态
官方定义:mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T>
on State
:必须混入到 StatefulWidget 的 State 类里使用。
为什么需要它
默认情况下,Flutter 的 ListView、PageView、TabBarView 出于性能考虑,会 销毁不可见的页面(状态 dispose 掉,重新进入时又会 rebuild)。
这样带来两个问题:
- 输入框内容丢失;
- 滑动位置重置;
- 请求过的数据需要重新加载。
AutomaticKeepAliveClientMixin
的目的就是:即使页面不可见,也保持它的 State 不被销毁。
完整代码示例
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'KeepAlive Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2, // 两个标签页
child: Scaffold(
appBar: AppBar(
title: const Text("AutomaticKeepAliveClientMixin 示例"),
bottom: const TabBar(
tabs: [
Tab(text: "没有 KeepAlive"),
Tab(text: "有 KeepAlive"),
],
),
),
body: const TabBarView(children: [NoKeepAlivePage(), KeepAlivePage()]),
),
);
}
}
// ========== 页面1:没有使用 AutomaticKeepAliveClientMixin ==========
class NoKeepAlivePage extends StatefulWidget {
const NoKeepAlivePage({super.key});
@override
State<NoKeepAlivePage> createState() => _NoKeepAlivePageState();
}
class _NoKeepAlivePageState extends State<NoKeepAlivePage> {
int counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Counter: $counter", style: const TextStyle(fontSize: 24)),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => counter++),
child: const Icon(Icons.add),
),
);
}
}
// ========== 页面2:使用 AutomaticKeepAliveClientMixin ==========
class KeepAlivePage extends StatefulWidget {
const KeepAlivePage({super.key});
@override
State<KeepAlivePage> createState() => _KeepAlivePageState();
}
class _KeepAlivePageState extends State<KeepAlivePage>
with AutomaticKeepAliveClientMixin {
int counter = 0;
@override
bool get wantKeepAlive => true; // 保持状态
@override
Widget build(BuildContext context) {
super.build(context); // 必须调用
return Scaffold(
body: Center(
child: Text("Counter: $counter", style: const TextStyle(fontSize: 24)),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => counter++),
child: const Icon(Icons.add),
),
);
}
}

如何使用
- 混入
AutomaticKeepAliveClientMixin
; wantKeepAlive => true
;super.build(context)
不能忘。
工作机制
AutomaticKeepAliveClientMixin
的工作机制是:
- 你的
State
混入了这个 Mixin,它会和 Flutter 的KeepAlive
机制交互。 - 当 Flutter 构建
TabBarView
、PageView
等滚动组件时,会询问子页面:“你要不要保持存活?” - 这个询问是通过
super.build(context)
触发的。
换句话说:
- 如果你 不调用
super.build(context)
,KeepAlive
的信息(wantKeepAlive
)就不会传递到父级。 - Flutter 就不知道你要保持页面,于是页面在切换后仍会被销毁(表现和没加 Mixin 一样)。
super.build(context)
super与build
class _KeepAlivePageState extends State<KeepAlivePage>
with AutomaticKeepAliveClientMixin {
int counter = 0;
@override
bool get wantKeepAlive => true; // 保持状态
@override
Widget build(BuildContext context) {
super.build(context); // 必须调用
return Scaffold(
body: Center(
child: Text("Counter: $counter", style: const TextStyle(fontSize: 24)),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => counter++),
child: const Icon(Icons.add),
),
);
}
}
问题一:_KeepAlivePageState
重写的是谁的build
?答:AutomaticKeepAliveClientMixin
class _KeepAlivePageState extends State<KeepAlivePage> with AutomaticKeepAliveClientMixin {
Dart 的方法解析顺序 (MRO) 是:
_KeepAlivePageState → AutomaticKeepAliveClientMixin → State
- 它会先找
_KeepAlivePageState
有没有build
。如果没有,就再往后面找。- 所有,我这里重写的是
AutomaticKeepAliveClientMixin
的build方法。
问题二:super是指哪个?指**AutomaticKeepAliveClientMixin
**
class _KeepAlivePageState extends State<KeepAlivePage> with AutomaticKeepAliveClientMixin {
在 Dart 中,
super
指的并不是某个“固定的类”,而是:当前类的直接父类或混入链中的上一个实现。
- 如果某个方法在
mixin
里有实现,那么super
就会指向混入链中“上一个”的实现;- 如果
mixin
没有实现该方法,super
就会指向extends
的父类。上面案例类的继承关系
State<KeepAlivePage> <-- 父类 ↑ AutomaticKeepAliveClientMixin <-- 混入,覆盖了 build() ↑ _KeepAlivePageState <-- 你写的类
为什么要 super.build(context)
?
// AutomaticKeepAliveClientMixin 里的 build 源码
@mustCallSuper
@override
Widget build(BuildContext context) {
if (wantKeepAlive && _keepAliveHandle == null) {
_ensureKeepAlive();
// Whenever wantKeepAlive's value changes (or might change), the
// subclass should call [updateKeepAlive].
// That will ensure that the keepalive is disabled (or enabled)
// without requiring a rebuild.
}
return const _NullWidget();
}
}
AutomaticKeepAliveClientMixin
的build
方法不会去渲染 UI,而是负责 插入 KeepAlive 逻辑。- 它会检查
wantKeepAlive
是否为true
,如果是,就调用_ensureKeepAlive()
,让 Flutter 知道 这个 Widget 不要被销毁。 - 返回的
_NullWidget()
本质上只是个占位,它不会显示在界面上(真正的 UI 是你在State.build
里写的Scaffold
等)。