Flutter学习日记-log6

本文最后更新于:2 年前

Flutter中文网


日志随笔

一、跨组件状态共享(Provider)

其实就是对普通写法的一种封装,采用泛型进行封装,提供一个继承于Widget的组件,将保存共享数据的入口和读取的入口封装在里面,对外提供统一的方法
此外,还封装了一个修改的方法,修改的方法在数据修改后需要通知主Widget进行刷新,我尝试采用callback回调进行通知,失败,因为静态方法无法访问成员变量,所以无法进行回调
demo中采用了继承Listenable的监听,当参数发生变化时,通知所有监听的地方,但是这样需要封装一个model的类出来,用来发出通知

文档中代码报错,无法运行,关于Listenable监听的逻辑以后再研究

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import 'dart:ffi';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'provider',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: '主页'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
var _counter = 0;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Provider(
data: _counter,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Builder(builder: (builder) {
return Text(
// 普通类型可以直接使用
Provider.of(builder).toString(),
);
}),
Builder(builder: (builder) {
return RaisedButton(
onPressed: () {
// 直接修改参数,然后通知状态变化
_counter++;
setState(() {});
},
child: Icon(Icons.add),
);
}),
],
),
),
changedCallBack: () {
return null;
},
),
);
}
}

// 声明一个通知类,里面包含一个通知的方法
class ProviderChangeedNotifier implements Listenable {
void notifyListeners() {
// 通知所有监听器,触发回调
print('notifyListeners');
}

@override
void addListener(listener) {
print('addListener');
}

@override
void removeListener(listener) {
print('removeListener');
}
}

// 继承通知类,负责保存数据参数和修改后进行通知
class ProviderModel extends ProviderChangeedNotifier {
var data = 0;

change<T extends ProviderChangeedNotifier>(params) {
data = params;
notifyListeners();
}
}

typedef ProviderSharedDataChangedCallBack = Future Function();

class Provider<T extends ProviderChangeedNotifier> extends StatefulWidget {
Provider({
Key key,
@required this.data,
this.child,
@required this.changedCallBack,
}) : super(key: key);
final T data;
final Widget child;
final ProviderSharedDataChangedCallBack changedCallBack;

@override
_ProviderState createState() => _ProviderState();

// 获取共享参数的方法
static T of<T extends ProviderChangeedNotifier>(context) {
return SharedData.of(context).data;
}

// 修改共享参数的方法
static void changeSharedData(data) {
// 此处无法调用changedCallBack属性进行回调操作
// changedCallBack();
}
}

class _ProviderState<T extends ProviderChangeedNotifier> extends State<Provider<T>> {
@override
Widget build(BuildContext context) {
return SharedData(
data: widget.data,
child: widget.child,
);
}
}

class SharedData<T extends ProviderChangeedNotifier> extends InheritedWidget {
SharedData({
Key key,
@required this.data,
Widget child,
}) : super(key: key, child: child);
final T data;

@override
bool updateShouldNotify(SharedData oldWidget) {
if (oldWidget.data == data) {
return false;
} else {
return true;
}
}

// 获取共享组件的方法
static SharedData of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType();
}
}

二、颜色和主题

三、异步UI更新(FutureBuilder、StreamBuilder)

四、对话框

未完待续