从MediaQuery看InheritedWidget的用法

  • 继承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<InheriedWidgetTester> {
  @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: <Widget>[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<InheriedWidgetA> {
  @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<InheriedWidgetB> {
  @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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容

  • 整理来自互联网 1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具...
    Ncompass阅读 1,537评论 0 6
  • 面试题参考1 : 面试题[http://www.cocoachina.com/ios/20150803/12872...
    江河_ios阅读 1,731评论 0 4
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,649评论 0 11
  • 重点掌握 3 类对象和方法 对象就是一个物体 类的独特存在就是一个实例,对实例进行操作叫做方法。方法可以应用于类或...
    Coder大雄阅读 1,258评论 0 2
  • 难得今天没有下雨,但气温依然很低。 装修行业上半年都是比较淡,春节以来,我们集成吊顶才开几天的工,趁着今天...
    王益军阅读 213评论 0 3