dart语言中,new XXX(),new可以省略。
先从无状态组件StatelessWidget和有状态组件StatefulWidget说起,
StatelessWidget无状态组件:
import "package:flutter/material.dart";
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyStatelessWidget(data: "xxx"),
],
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key, this.data}) : super(key: key);
final data;
@override
Widget build(BuildContext context) {
return Text(data, style: TextStyle(fontSize: 50));
}
// @override
// void didUpdateWidget(MyStateful oldWidget) {
// super.didUpdateWidget(oldWidget);
// print("didUpdateWidget");
// }
}
上面是非常简单的一段完整的代码,有几点要说明:
- 继承
StatelessWidget类的组件只能被build渲染一次,即只会调用一次bulid函数,调用完一次后,此函数和Home类会出栈释放内存,而所渲染的组件则被挂载到渲染树上。 - 给
data用final关键字的原因是:正如第一条所理解,数据一旦被赋值,便不能被再次修改,去掉final会报错。也可以直接赋初始值对Text("xxx")。 - 上面被注释掉的 生命周期函数 不能在的
StatelessWidget无状态组件中使用,会报错,只能在StatefulWidget有状态组件中使用。
StatefulWidget有状态组件:
import "package:flutter/material.dart";
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyStatefulWidget(),
],
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidget createState() => new _MyStatefulWidget();
}
class _MyStatefulWidget extends State<MyStatefulWidget> {
String data = "data";
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
Text(data),
FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
]);
}
//自定义的函数reSetState():
void reSetState() {
data = "newData"; //这样直接修改并不会重新被渲染。
//必须在setState()函数中修改才能被重新渲染。
setState(() {
data = "newData";
});
}
//生命周期函数:
@override
void didUpdateWidget(MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
}
上面是非常简单的一段完整的代码,有几点要说明:
- 有状态组件中的
data值可以被多次修改,但是直接修改data值并不会重新被build渲染一遍,而必须调用setState()函数才能重新渲染。 - 每渲染一次,都会调用一次
build函数,也都会调用一次这个生命周期函数didUpdateWidget()。 - 每次
didUpdateWidget()的调用,都意味着MyStatefulWidget整个有状态组件将被重新渲染一遍。 - 正如第3条所理解,这意味着,如果
Column容器中有无数个Text(data)的兄弟组件,每次didUpdateWidget()的调用,都会将其所有组件重新渲染一遍,这对性能有一定的影响。 - 然而,我们只是修改了
Text(data)中的data数据,没必要带上其他的组件一起渲染吧,那么如何解决这问题呢?
这回Provider包就起作用了。
先从Text(data)组件说起,查看Text(data)组件源码,发现它继承了StatelessWidget,
源码:
class Text extends StatelessWidget {
const Text(
this.data,
...省略其他源码...
);
}
- 也就是说,
Text(data)是个StatelessWidget无状态组件,data参数只能赋值一次,??? - 问题来了,
data只能被赋值一次,那为什么在有状态组件中,Text(data)中的data能被修改? - 有两个原因:
data是在有状态组件被定义的,在未调用setState()时,data的变动,和Text组件无关。带有初始值的Text组件挂载到渲染树上,一直未动。data在有状态组件中被修改时,调用setState()是将整个有状态组件重新渲染,而并非渲染单个Text组件。并非是将渲染树上的单个Text组件重新挂载,而是将整个有状态组件进行重新挂载。- 那么我们修改
data时,如何才能只重新渲染单个Text组件,而不去渲染整个有状态组件呢?
-----Provider-----开启观察者模式
观察谁?
拿上面的有状态组件为例:
String data = "data";
Widget build(BuildContext context) {
return Column(children: <Widget>[
FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
Text(data),
FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
]);
}
data数据是动态的,我们对data值的修改必然是在父组件或祖父组件中进行修改,而Text组件和2个FlatButton组件是兄弟组件。因此我们要对这3个兄弟组件进行观察,我们可以直接观察Column组件。
-----跨组件共享数据-----
在观察之前,我们先介绍Provider的第二个作用:跨组件共享数据。
我们有个需求:A组件和B组件有一个数据要相互访问。若这个数据定义中A组件中,B组件便无法访问,若定义在B组件中,A组件便无法访问。
那该如何做到跨组件访问呢?
上面我们已经对Column进行了观察,这意味着Column的所有的子组件已经在我们的掌控之中。
- 在观察者观察前,我们要创建一个
ChangeNotifier类,这个类代表了组件之间访问数据的中间层,观察者所观察的Column组件中所有数据都放到这个中间层类ChangeNotifier上,只要是被观察者所观察的组件,都能访问ChangeNotifier类,都能访问到这个类中的数据。
创建中间层类要继承ChangeNotifier,我们在里面存放一个count数据和两个函数:
class MyNotifier extends ChangeNotifier {
int count = 0;
add() {
count++;
print(count);
}
minus() {
count--;
print(count);
}
}
-----启动观察-----
上面一直在提观察,观察的对象是Column组件,那么要如何进行观察呢?
我们需将Column组件包裹在观察者内:
String data = "data";
@override
Widget build(BuildContext context) {
return MultiProvider( //观察者
providers: [
ChangeNotifierProvider(create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column( //需要被观察的组件
children: <Widget>[
FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
Text(data),
FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {}),
],
),
);
}
我们要实现的功能:点击“+”按钮,data加1,点击“-”按钮,data减1。
先将FlatButton抽离出来:
AddButton按钮只需渲染一遍,因此继承StatelessWidget:
class AddButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)), onPressed: () => {});
}
}
MinusButton按钮只需渲染一遍,因此继承StatelessWidget:
class MinusButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)), onPressed: () => {});
}
}
Text(data)中的数据需要被更改,因此留在MyStatefulWidget类中:
String data = "data";
@override
Widget build(BuildContext context) {
return MultiProvider( //观察者
providers: [
ChangeNotifierProvider(create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column( //需要被观察的组件
children: <Widget>[
AddButton() ,
Text(data),
MinusButton(),
],
),
);
}
整理后的完整代码:
import "package:flutter/material.dart";
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyStatelessWidget(data: "xxx"),
MyStatefulWidget(),
],
),
),
);
}
}
//普通的无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key, this.data}) : super(key: key);
final data;
@override
Widget build(BuildContext context) {
return Text(data, style: TextStyle(fontSize: 50));
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//被观察者观察的有状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidget createState() => new _MyStatefulWidget();
}
class _MyStatefulWidget extends State<MyStatefulWidget> {
String data = "data";
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
Text(data),
MinusButton(),
],
),
);
}
void reSetState() {
data = "newData";
setState(() {
data = "newData";
});
}
@override
void didUpdateWidget(MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//中间层↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyNotifier extends ChangeNotifier {
int count = 0;
add() {
count++;
print(count);
}
minus() {
count--;
print(count);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//单独抽离出来的2个无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class AddButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {},
);
}
}
class MinusButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {},
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
跨组件访问共享数据
哪个组件需要访问,哪个组件就引入下面这段代码(前提是其组件被观察者观察):
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
比如:
//单独抽离出来的2个无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class AddButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context); //引入
return FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.add()}, //访问其方法
);
}
}
class MinusButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);// 引入
return FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.minus()}, //访问其方法
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
在模拟器中点击加减按钮,控制台会print(count)打印出conut值,但是data数据没有改变,
我们再观察一下下面代码:
//被观察者观察的有状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidget createState() => new _MyStatefulWidget();
}
class _MyStatefulWidget extends State<MyStatefulWidget> {
String data = "data";
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
Text(data),
MinusButton(),
],
),
);
}
void reSetState() {
data = "newData";
setState(() {
data = "newData";
});
}
@override
void didUpdateWidget(MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
Text(data)中的data使用的并不是中间层的数据,而是自身组件中的数据,
我们把String data = "data"和reSetState()函数代码删掉,在build函数中添加:
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
并把Text(data)改为Text(mainProvider.count.toString())。
但是发现运行会报错,原因是在观察者观察前,还没有把中间层创建出来,因此这里不能引用中间层。
但我们可以把Text(mainProvider.count.toString())也抽离出来,这样就可以在创建中间层之后引入MyNotifier了:
class TextWedget extends StatelessWidget{
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return Text(mainProvider.count.toString());
}
}
整理后的完整代码:
import "package:flutter/material.dart";
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyStatelessWidget(data: "xxx"),
MyStatefulWidget(),
],
),
),
);
}
}
//普通的无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key, this.data}) : super(key: key);
final data;
@override
Widget build(BuildContext context) {
return Text(data, style: TextStyle(fontSize: 50));
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//被观察者观察的有状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidget createState() => new _MyStatefulWidget();
}
class _MyStatefulWidget extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
TextWedget(),
MinusButton(),
],
),
);
}
@override
void didUpdateWidget(MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//中间层↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyNotifier extends ChangeNotifier {
int count = 0;
add() {
count++;
print(count);
}
minus() {
count--;
print(count);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//单独抽离出来的3个无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class TextWedget extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return Text(mainProvider.count.toString());
}
}
class AddButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.add()},
);
}
}
class MinusButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.minus()},
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
我们在模拟器中点击加减按钮,观察发现仍只是控制台打印数字,但模拟器data却没有改变。
这是因为我们只是修改了count的值,并没有要求让值重新渲染,调用notifyListeners()才能将修改的值重新渲染,notifyListeners()等价于setState()函数。
//中间层↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyNotifier extends ChangeNotifier {
int count = 0;
add() {
count++;
print(count);
notifyListeners(); //重新渲染
}
minus() {
count--;
print(count);
notifyListeners(); //重新渲染
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
但引出了几个问题:
- 在
Text(mainProvider.count.toString())中包了一个可被修改的数据,但为什么TextWedget要继承StatelessWidget,而不继承StatefulWidget,继承StatefulWidget反而会报错?
- 答:依我的理解,可能是
Provider开发者故意约束的吧,被观察者监控的组件,都不能继承StatefulWidget,这样让我们很清晰的认识到所有动态数据都存放到中间层里,而我们创建的组件都只需是静态的,省了性能又省事。
- 既然
TextWedget继承了继承StatelessWidget,那么TextWedget是个无状态组件,只能被build渲染一次,因此Text(mainProvider.count.toString())数据被修改,并不会重新build渲染一遍TextWedget组件。而TextWedget的父组件MyStatefulWidget组件是有状态的组件,那么数据被修改,重新build渲染也只能重新渲染MyStatefulWidget整个组件,而渲染整个MyStatefulWidget组件,必然会调用MyStatefulWidget组件中的didUpdateWidget()函数,然而该函数并没有被调用,这是为什么呢?
- 答:
Text(mainProvider.count.toString())被修改,并没有将MyStatefulWidget整个组件重新渲染,而是由中间层来控制重新渲染。观察者监控着每个组件,这意味着一旦有数据被修改,被修改的数据所对应的组件将被中间层控制重新渲染。
既然只是中间层来控制重新渲染,那么我们可以把所有组件都继承StatelessWidget以便省事:
原来的StatefulWidget代码:
//被观察者观察的有状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidget createState() => new _MyStatefulWidget();
}
class _MyStatefulWidget extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
TextWedget(),
MinusButton(),
],
),
);
}
@override
void didUpdateWidget(MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget");
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
改成StatelessWidget形式:
class MyStatefulWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
TextWedget(),
MinusButton(),
],
),
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
完整的代码:
import "package:flutter/material.dart";
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
MyStatelessWidget(data: "xxx"),
MyStatefulWidget(),
],
),
),
);
}
}
//普通的无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key, this.data}) : super(key: key);
final data;
@override
Widget build(BuildContext context) {
return Text(data, style: TextStyle(fontSize: 50));
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//被观察者观察的有状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyStatefulWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
//观察者
providers: [
ChangeNotifierProvider(
create: (context) => MyNotifier()), //观察者所依赖的中间层,可依赖多个
],
child: Column(
//需要被观察的组件
children: <Widget>[
AddButton(),
TextWedget(),
MinusButton(),
],
),
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//中间层↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class MyNotifier extends ChangeNotifier {
int count = 0;
add() {
count++;
print(count);
notifyListeners();
}
minus() {
count--;
print(count);
notifyListeners();
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//单独抽离出来的3个无状态组件↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
class TextWedget extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return Text(mainProvider.count.toString());
}
}
class AddButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return FlatButton(
child: Text("+", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.add()},
);
}
}
class MinusButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
MyNotifier mainProvider = Provider.of<MyNotifier>(context);
return FlatButton(
child: Text("-", style: TextStyle(fontSize: 50)),
onPressed: () => {mainProvider.minus()},
);
}
}
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
这回代码清晰多了。
本人刚入门不久,由于知识浅薄难以深入,此文章肯定很多地方理解的不准确,轻喷~