源码
/// AutomaticKeepAliveClientMixin 可以快速的实现页面缓存功能,
/// 但是通过混入的方式实现不是很优雅,所以我们有必要对 AutomaticKeepAliveClientMixin 混入进行封装
import 'package:flutter/material.dart';
class KeepAliveWrapper extends StatefulWidget {
const KeepAliveWrapper(
{Key? key, @required this.child, this.keepAlive = true})
: super(key: key);
//子元素
final Widget? child;
//是否缓存子元素状态,默认 true
final bool keepAlive;
@override
State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
return widget.child!;
}
@override
bool get wantKeepAlive => widget.keepAlive;
@override
void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
if (oldWidget.keepAlive != widget.keepAlive) {
// keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中
updateKeepAlive();
}
super.didUpdateWidget(oldWidget);
}
}
使用:
1、引入头文件
2、包裹在要缓存的组件外层
import 'package:flutter/material.dart';
import 'KeepAliveWrapper.dart'; //导入头文件
void main(List<String> args) {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false, //隐藏右上角 DEBUG 图标
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void dispose() {
//销毁
super.dispose();
_tabController.dispose();
}
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
_tabController.addListener(() {
if (_tabController.animation?.value == _tabController.index) {
print(_tabController.index); //获取点击或滑动页面的索引值
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(50), //设置 appBar 的高度
child: AppBar(
backgroundColor: const Color.fromARGB(255, 253, 247, 247),
elevation: 10,
title: SizedBox(
height: 30, //设置 tabbar 的高度
child: TabBar(
// isScrollable: true, //如果多个按钮的话可以滑动
indicatorColor: Colors.red,
labelColor: Colors.red,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
controller: _tabController, //注意
tabs: const [
Tab(child: Text("热销", style: TextStyle(color: Colors.black))),
Tab(child: Text("推荐", style: TextStyle(color: Colors.black)))
]),
),
),
),
body: TabBarView(
controller: _tabController,//注意
children: [
KeepAliveWrapper( //添加缓存
child: ListView(
children: const <Widget>[
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("第一个tab")),
ListTile(title: Text("最后一个tab")),
],
)),
KeepAliveWrapper( //添加缓存
child: ListView(
children: const <Widget>[
ListTile(title: Text("第二个tab")),
ListTile(title: Text("第二个tab")),
ListTile(title: Text("第二个tab"))
],
))
]),
);
}
}
网友评论