Flutter状态State管理
参考:《Flutter状态State管理》
InheritedWidget使用
- 示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class UserInfo {
String name;
int age;
}
class HYCounterWidget extends InheritedWidget {
// 1.共享的数据
final int counter;
// 2.定义构造方法
HYCounterWidget({this.counter, Widget child}): super(child: child);
// 3.获取组件最近的当前InheritedWidget
static HYCounterWidget of(BuildContext context) {
// 沿着Element树, 去找到最近的HYCounterElement, 从Element中取出Widget对象
return context.dependOnInheritedWidgetOfExactType();
}
// 4.绝对要不要回调State中的didChangeDependencies
// 如果返回true: 执行依赖当期的InheritedWidget的State中的didChangeDependencies
@override
bool updateShouldNotify(HYCounterWidget oldWidget) {
return oldWidget.counter != counter;
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue, splashColor: Colors.transparent),
home: HYHomePage(),
);
}
}
class HYHomePage extends StatefulWidget {
@override
_HYHomePageState createState() => _HYHomePageState();
}
class _HYHomePageState extends State<HYHomePage> {
int _counter = 100;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InheritedWidget"),
),
body: HYCounterWidget(
counter: _counter,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HYShowData01(),
HYShowData02()
],
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
_counter++;
});
},
),
);
}
}
class HYShowData01 extends StatefulWidget {
@override
_HYShowData01State createState() => _HYShowData01State();
}
class _HYShowData01State extends State<HYShowData01> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("执行了_HYShowData01State中的didChangeDependencies");
}
@override
Widget build(BuildContext context) {
int counter = HYCounterWidget.of(context).counter;
return Card(
color: Colors.red,
child: Text("当前计数: $counter", style: TextStyle(fontSize: 30),),
);
}
}
class HYShowData02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
int counter = HYCounterWidget.of(context).counter;
return Container(
color: Colors.blue,
child: Text("当前计数: $counter", style: TextStyle(fontSize: 30),),
);
}
}
Provider使用
- 文件结构:
- user_info.dart
class UserInfo {
String nickname;
int level;
String imageURL;
UserInfo(this.nickname, this.level, this.imageURL);
}
- viewmodel\user_view_model.dart
import 'package:flutter/material.dart';
import '../model/user_info.dart';
class HYUserViewModel extends ChangeNotifier {
UserInfo _user;
HYUserViewModel(this._user);
UserInfo get user => _user;
set user(UserInfo value) {
_user = value;
notifyListeners();
}
}
- viewmodel\counter_view_model.dart
import 'package:flutter/material.dart';
// 1.创建自己需要共享的数据
class HYCounterViewModel extends ChangeNotifier {
int _counter = 100;
int get counter => _counter;
set counter(int value) {
_counter = value;
notifyListeners();
}
}
- viewmodel\initialize_providers.dart
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'counter_view_model.dart';
import 'user_view_model.dart';
import '../model/user_info.dart';
List<SingleChildWidget> providers = [
ChangeNotifierProvider(create: (ctx) => HYCounterViewModel(),),
ChangeNotifierProvider(create: (ctx) => HYUserViewModel(UserInfo("why", 29, "abc")),),
];
- provider_basic.dart
import 'package:flutter/material.dart';
import 'viewmodel/counter_view_model.dart';
import 'package:provider/provider.dart';
/**
* 1.创建自己需要共享的数据
* 2.在应用程序的顶层ChangeNotifierProvider
* 3.在其它位置使用共享的数据
* > Provider.of: 当Provider中的数据发生改变时, Provider.of所在的Widget整个build方法都会重新构建
* > Consumer(相对推荐): 当Provider中的数据发生改变时, 执行重新执行Consumer的builder
* > Selector: 1.selector方法(作用,对原有的数据进行转换) 2.shouldRebuild(作用,要不要重新构建)
*/
void main() {
runApp(
// 2.在应用程序的顶层ChangeNotifierProvider
ChangeNotifierProvider(
create: (ctx) => HYCounterViewModel(),
child: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue, splashColor: Colors.transparent),
home: HYHomePage(),
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("列表测试"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HYShowData01(),
HYShowData02()
],
),
),
floatingActionButton: Selector<HYCounterViewModel, HYCounterViewModel>(
selector: (ctx, counterVM) => counterVM,
shouldRebuild: (prev, next) => false,
builder: (ctx, counterVM, child) {
print("floatingActionButton build方法被执行");
return FloatingActionButton(
child: child,
onPressed: () {
counterVM.counter += 1;
},
);
},
child: Icon(Icons.add),
)
);
}
}
class HYShowData01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 3.在其它位置使用共享的数据
int counter = Provider.of<HYCounterViewModel>(context).counter;
print("data01的build方法");
return Container(
color: Colors.blue,
child: Column(
children: <Widget>[
Text("当前计数: $counter", style: TextStyle(fontSize: 30),),
],
),
);
}
}
class HYShowData02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("data02的build方法");
return Container(
color: Colors.red,
child: Consumer<HYCounterViewModel>(
builder: (ctx, counterVM, child) {
print("data02 Consumer build方法被执行");
return Text("当前计数: ${counterVM.counter}", style: TextStyle(fontSize: 30),);
},
),
);
}
}