- 继承InheriedWidget
class MediaQuery extends InheritedWidget {
- 包含一个需要共享的变量,这里为data
!! 坑点来了
这里必须还有一个child字段,必传,但这还不是最关键的, 最关键的是super也需要把这个字段带上
哪些widget需要共享数据,就放到child下面
const MediaQuery({
Key key,
@required this.data,
@required Widget child,
}) : assert(child != null),
assert(data != null),
super(key: key, child: child);
final MediaQueryData data;
- 实现updateShouldNotify方法,一般是比较该变量是否相同,不同则更新
@override
bool updateShouldNotify(MediaQuery oldWidget) => data != oldWidget.data;
- 实现一个静态的of方法,用来获取这个共享变量,传入的参数固定为context,方法体中固定使用 context.inheritFromWidgetOfExactType(xxx);的方式获取xxx
这个xxx即我们实现的继承自InheritedWidget的子类,这里是MediaQuery
static MediaQueryData of(BuildContext context, { bool nullOk = false }) {
assert(context != null);
assert(nullOk != null);
final MediaQuery query = context.inheritFromWidgetOfExactType(MediaQuery);
if (query != null)
return query.data;
if (nullOk)
return null;
throw FlutterError(
'MediaQuery.of() called with a context that does not contain a MediaQuery.\n'
'No MediaQuery ancestor could be found starting from the context that was passed '
'to MediaQuery.of(). This can happen because you do not have a WidgetsApp or '
'MaterialApp widget (those widgets introduce a MediaQuery), or it can happen '
'if the context you use comes from a widget above those widgets.\n'
'The context used was:\n'
' $context'
);
}
贴一个示例代码:
import 'package:flutter/material.dart';
import 'package:flutter_ui_common/constants.dart';
class InheriedWidgetTester extends StatefulWidget {
@override
_InheriedWidgetTesterState createState() => _InheriedWidgetTesterState();
}
class _InheriedWidgetTesterState extends State {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
var testModel = TestModel(age: 1);
var scaffold = new Scaffold(
appBar: AppBar(title: Text("test inheriedwidget")),
body: Column(
children: [InheriedWidgetA(), InheriedWidgetB()],
),
);
var testModelQuery = _TestModelQuery(
data: testModel,
child: scaffold,
);
return testModelQuery;
}
}
class InheriedWidgetA extends StatefulWidget {
@override
_InheriedWidgetAState createState() => _InheriedWidgetAState();
}
var data = "显示修改的age";
class _InheriedWidgetAState extends State {
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 80,
color: white,
child: RaisedButton(
child: Text(
data,
style: TextStyle(color: black, fontSize: 15),
),
onPressed: () {
int age = _TestModelQuery.of(context).age;
print('修改 的age'+age.toString());
setState(() {
data = age.toString();
});
}),
);
}
}
class InheriedWidgetB extends StatefulWidget {
@override
_InheriedWidgetBState createState() => _InheriedWidgetBState();
}
class _InheriedWidgetBState extends State {
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 80,
color: white,
child: RaisedButton(
child: Text(
"修改age为9",
style: TextStyle(color: black, fontSize: 15),
),
onPressed: () {
var testModel = _TestModelQuery.of(context);
testModel.age = 9;
}),
);
}
}
class TestModel {
TestModel({this.age});
var age;
}
class _TestModelQuery extends InheritedWidget {
const _TestModelQuery({Key key, this.data, Widget child}) : super(key: key, child: child);
final TestModel data;
/// 获取共享数据
static TestModel of(BuildContext context) {
_TestModelQuery query =
context.inheritFromWidgetOfExactType(_TestModelQuery);
return query.data;
}
@override
bool updateShouldNotify(_TestModelQuery oldWidget) =>
data.age != oldWidget.data.age;
}
github