博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flutter 组件通信(父子、兄弟)
阅读量:4082 次
发布时间:2019-05-25

本文共 10370 字,大约阅读时间需要 34 分钟。

一,概述 

   flutter一个重要的特性就是组件化。组件分为两种状态,一种是StatefulWidget有状态组件,一种是StatelessWidget无状态组件。 无状态组件不能更新状态,有状态组件具有类似刷新的机制,可更改状态。

  功能模块都可以通过继承两种状态组件实现功能模块封装。组件间通信,一般存在一下两种关系。

      • 父子组件通信
      • 兄弟组件通信       

二, 通信实现方式

  • 回调通信
    • 需求“点击子组件,修改父组件的背景颜色与子组件背景颜色一致”
    • 代码实现

      复制代码

      //父组件class ParentWidget extends StatefulWidget {  final String title;  ParentWidget({Key key,this.title}):super(key:key);  @override  State
      createState() { return new ParentWidgetState(); }}class ParentWidgetState extends State
      { Color containerBg = Colors.orange; //回调函数 void changeBackgroundColor(Color newColor){ setState(() { containerBg = newColor;//修改状态 }); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Center( child: new GestureDetector( onTap: (){ changeBackgroundColor(Colors.orange); }, child: new Container( width: 300, height: 300, color: containerBg, alignment: Alignment.center, child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children:
      [ new childrenA(childrenACallBack: changeBackgroundColor), new childrenB(childrenBCallBack: changeBackgroundColor), ], ), ), ) ), ); }}//子组件(组件A)class childrenA extends StatelessWidget { //定义接收父类回调函数的指针
      final ValueChanged
      childrenACallBack; childrenA({Key key,this.childrenACallBack}):super(key:key);
      @override  Widget build(BuildContext context) {    return new GestureDetector(      onTap: (){       //调用回调函数传值        childrenACallBack(Colors.green);      },      child: new Container(          width: 80,          height: 80,          color: Colors.green,          child: new Text('ChildrenA'),      ),    );  }}//子组件(组件B)class childrenB extends StatelessWidget {  final ValueChanged
      childrenBCallBack; childrenB({Key key,this.childrenBCallBack}):super(key:key); @override Widget build(BuildContext context) { return new GestureDetector( onTap:(){ childrenBCallBack(Colors.red); }, child: new Container( width: 80, height: 80, color: Colors.red, child: new Text('ChildredB'), ), ); }}

      复制代码

       

    • 功能实现

    • 使用场景:一般用于子组件对父组件传值。
       
  • InheritedWidget 数据共享

    • 场景:业务开发中经常会碰到这样的情况,多个Widget需要同步同一份全局数据,比如点赞数、评论数、夜间模式等等。
    • 代码实现:

      复制代码

      import 'package:flutter/material.dart';void main() => runApp(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,              ),      home: new InheritedWidgetTestContainer(),    );  }}//模型数据class InheritedTestModel {  final int count;  const InheritedTestModel(this.count);}//哨所(自定义InheritedWidget类)class  InheritedContext extends InheritedWidget {  //构造函数  InheritedContext({    Key key,    @required this.inheritedTestModel,    @required this.increment,    @required this.reduce,    @required Widget child  }):super(key:key,child:child);  //变量  final InheritedTestModel inheritedTestModel;  final Function() increment;  final Function() reduce;    //静态方法  static InheritedContext of(BuildContext context){    InheritedContext contexts = context.inheritFromWidgetOfExactType(InheritedContext);    return context.inheritFromWidgetOfExactType(InheritedContext);  }  //是否重建取决于Widget组件是否相同  @override  bool updateShouldNotify(InheritedContext oldWidget) {    return inheritedTestModel != oldWidget.inheritedTestModel;  }}class TestWidgetA extends StatelessWidget {  @override  Widget build(BuildContext context) {    final inheritedContext = InheritedContext.of(context);    return new Padding(      padding: const EdgeInsets.only(left: 10.0,top: 10.0,right: 10.0),      child: new RaisedButton(        textColor: Colors.black,        child: new Text('+'),        onPressed:inheritedContext.increment      ),    );  }}class TestWidgetB extends StatelessWidget {  @override  Widget build(BuildContext context) {   final inheritedContext = InheritedContext.of(context);    return new Padding(      padding: const EdgeInsets.only(left: 10,top: 10,right: 10.0),      child: new RaisedButton(        textColor: Colors.black,        child: new Text('-'),        onPressed: inheritedContext.reduce      ),    );  }}class TestWidgetC extends StatelessWidget {  @override  Widget build(BuildContext context) {    final inheritedContext = InheritedContext.of(context);    final inheritedTestModel = inheritedContext.inheritedTestModel;    return new Padding(      padding: const EdgeInsets.only(left: 10.0,top: 10.0,right: 10.0),      child: new RaisedButton(        textColor: Colors.black,        child: new Text('${inheritedTestModel.count}'),        onPressed: (){                  },      ),    );  }}class InheritedWidgetTestContainer extends StatefulWidget {  @override  State
      createState() { return new InheritedWidgetTestContainerState(); }}class InheritedWidgetTestContainerState extends State
      { InheritedTestModel _inheritedTestModel; _initData(){ _inheritedTestModel = new InheritedTestModel(0); } @override void initState() { _initData(); super.initState(); } _incrementCount(){ setState(() { _inheritedTestModel = new InheritedTestModel(_inheritedTestModel.count + 1); }); } _reduceCount(){ setState(() { _inheritedTestModel = new InheritedTestModel(_inheritedTestModel.count - 1); }); } @override Widget build(BuildContext context) { return new InheritedContext( inheritedTestModel: _inheritedTestModel, increment: _incrementCount, reduce: _reduceCount, child: new Scaffold( appBar: new AppBar( title: new Text('InheritedWidgetTest'), ), body: new Center( child: new Column( children:
      [ new TestWidgetA(), new TestWidgetB(), new TestWidgetC(), ], ), ) ), ); }}

      复制代码

    • 功能实现
       
    • 使用场景

      一般用于父组件对子组件的跨组件传值。

  • Global Key通信
    GlobalKey能够跨Widget访问状态。
    • 需求“点击A子组件,修改B子组件的背景颜色为指定的‘蓝色”
    • 代码实现

      复制代码

      //父组件class ParentWidget extends  StatefulWidget {  @override  State
      createState() { return new ParentWidgetState(); }}class ParentWidgetState extends State
      { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('组件化'), ), body: new Center( child: new Container( color: Colors.grey, width: 200, height: 200, child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children:
      [ new SubWidgetA(key: subAkey), new SubWidgetB(key: subBkey) ], ), ), ), ); }}//子组件Aclass SubWidgetA extends StatefulWidget { SubWidgetA({Key key}):super(key:key); @override State
      createState() { return new SubWidgetAState(); }}class SubWidgetAState extends State
      { Color _backgroundColors = Colors.red;//红色 void updateBackGroundColors(Color colos){ setState(() { _backgroundColors = colos; }); } @override Widget build(BuildContext context) { return new GestureDetector( onTap: (){ subBkey.currentState.updateBackGroundColors(Colors.blue); setState(() { _backgroundColors = Colors.red; }); }, child: new Container( width: 80, height: 80, color:_backgroundColors, alignment: Alignment.center, child: new Text('SubWidgetA'), ), ); }}//子组件Bclass SubWidgetB extends StatefulWidget { SubWidgetB({Key key}):super(key:key); @override State
      createState() { // TODO: implement createState return new SubWidgetBState(); }}class SubWidgetBState extends State
      { Color _backgroundColors = Colors.green;//绿色 void updateBackGroundColors(Color colos){ setState(() { _backgroundColors = colos; }); } @override Widget build(BuildContext context) { return new GestureDetector( onTap: (){ subAkey.currentState.updateBackGroundColors(Colors.blue); setState(() { _backgroundColors = Colors.green; }); }, child: new Container( width: 80, height: 80, color: _backgroundColors, alignment: Alignment.center, child: new Text('SubWidgetB'), ), ); }}

      复制代码

    • 功能实现
    • 使用场景:一般用于跨组件访问状态
  • ValueNotifier通信 
     ValueNotifier是一个包含单个值的变更通知器,当它的值改变的时候,会通知它的监听。
     
    1. 定义ValueNotifierData类,继承ValueNotifier
      class ValueNotifierData extends ValueNotifier
      { ValueNotifierData(value) : super(value);}
    1. 定义_WidgetOne,包含一个ValueNotifierData的实例。
      class _WidgetOne extends StatefulWidget {  _WidgetOne({this.data});  final ValueNotifierData data;  @override  _WidgetOneState createState() => _WidgetOneState();}
    1. _WidgetOneState中给ValueNotifierData实例添加监听。

      复制代码

      @overrideinitState() {  super.initState();  widget.data.addListener(_handleValueChanged);  info = 'Initial mesage: ' + widget.data.value;} void _handleValueChanged() {    setState(() {      info = 'Message changed to: ' + widget.data.value;    });

      复制代码

    1. ValueNotifierCommunication组件中实例化_WidgetOne,可以通过改变ValueNotifierData实例的value来触发_WidgetOneState的更新。

      复制代码

      @overrideWidget build(BuildContext context) {  ValueNotifierData vd = ValueNotifierData('Hello World');  return Scaffold(    appBar: AppBar(title: Text('Value Notifier Communication'),),    body: _WidgetOne(data: vd),    floatingActionButton: FloatingActionButton(child: Icon(Icons.refresh),onPressed: () {      vd.value = 'Yes';    }),  );}

      复制代码

     
  • 第三方插件
      在这里运用event_bus来实现传值,用于组件与组件之间的传值。
    • event_bus 
      • 引入插件
        import 'package:event_bus/event_bus.dart';
      • event_bus用法。

        • 新建消息监测类

          import 'package:event_bus/event_bus.dart';  EventBus eventBus = new EventBus();  class TransEvent{   String text;   TransEvent(this.text);  }
        • 监测类变化

          eventBus.on
          ().listen((TransEvent data) => show(data.text));void show(String val) { setState(() { data = val; });}
        • 触发消息变化

          eventBus.fire(new TransEvent('$inputText'));
      • 使用场景:这样我们就可以根据这些来实现组件之间的传值。

转载地址:http://yuhni.baihongyu.com/

你可能感兴趣的文章
Linux下用math.h头文件
查看>>
Linux中用st_mode判断文件类型
查看>>
Ubuntu修改host遇到unable to resolve host
查看>>
路由选择算法
查看>>
Objective-C 基础入门(一)
查看>>
Objective-C 基础入门(三) 读写文件与回调
查看>>
C++ STL标准库与泛型编程(一)概述
查看>>
C++ STL标准库与泛型编程(四)Deque、Queue、Stack 深度探索
查看>>
C++ STL标准库 算法
查看>>
JVM内存模型_Minor GC笔记
查看>>
SpringCloud学习之PassCloud——(一)PassCloud源代码下载
查看>>
Linux下安装Python环境并部署NLP项目
查看>>
Nginx篇-springCloud配置Gateway+Nginx进行反向代理和负载均衡
查看>>
Nginx篇-Nginx配置动静分离
查看>>
缓存篇-Redis缓存失效以及解决方案
查看>>
缓存篇-使用Redis进行分布式锁应用
查看>>
缓存篇-Redisson的使用
查看>>
phpquery抓取网站内容简单介绍
查看>>
找工作准备的方向(4月22日写的)
查看>>
关于fwrite写入文件后打开查看是乱码的问题
查看>>