美文网首页Flutter
四、Flutter之组件间通信

四、Flutter之组件间通信

作者: 夏_Leon | 来源:发表于2019-02-26 15:36 被阅读506次

这里学了两种通信方式,一种是回调、另一种是借用第三方库event_bus,其他的还有GlobalKey、ValueNotifier、Redux等,后续再研究。

一、回调

组件间通信可以用回调方式,这里不需要像java新建一个接口类再实现,Dart是支持把方法作为对象传递的,也就是说可以直接把需要回调的方法作为变量传给目标。

/**
 * 父子、兄弟组件通信
 */
class WidgetContactDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Material(
        child: new Scaffold(
      appBar: new AppBar(
        title: new Text("组件间通信"),
      ),

      //主体
      body: new ParentWidget(),
    ));
  }
}

//父组件
class ParentWidget extends StatefulWidget {
  @override
  State createState() {
    return _ParentWidget();
  }
}

class _ParentWidget extends State<ParentWidget> {
  var bgColor; //父组件背景色
  var btnColor; //子组件背景色

  changeParentColor(color) {
    setState(() {
      bgColor = color;
    });
  }

  changeButtonColor() {
    setState(() {
      btnColor = RandomColor().get();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      color: bgColor,
      child: Column(
        children: <Widget>[
          RaisedButton(
            onPressed: changeButtonColor,
            child: Text('Button1,点击修改button2背景色'),
          ),
          //这里把方法changeParentColor和变量btnColor传入MyButton,如果changeParentColor是无参函数,可以直接用MyButton(changeParentColor,btnColor),
          MyButton((c) => changeParentColor(c), btnColor),
        ],
      ),
    );
  }
}

//子组件按钮,需要传入一个点击事件callback和一个背景色btnColor,点击时会调用callback,而btnColor在外部修改的时候,子组件也会响应修改。
class MyButton extends StatefulWidget {
  Function callback;
  var btnColor;

  //dart构造函数,可以直接把传入参数赋值给相应变量
  MyButton(this.callback, this.btnColor);

  //下面这种写法的构造函数支持MyButton(callback:(c)=>changeParentColor(c),btnColor:btnColor),
//  MyButton({Key key,this.callback,this.btnColor}) : super(key:key) ;

  @override
  State createState() {
    return _MyButton();
  }
}

class _MyButton extends State<MyButton> {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      //State里可以通过widget访问其StatefulWidget里的变量,此处常见错误!不能写作widget.callback(Colors.black12)
      onPressed: () => widget.callback(RandomColor().get()),
      child: Text('Button2,点击修改父控件背景色'),
      color: widget.btnColor,
    );
  }
}

//随机颜色类
class RandomColor {
  final bgColors = [
    Colors.white,
    Colors.yellow,
    Colors.orange,
    Colors.cyan,
    Colors.lime,
    Colors.pinkAccent
  ];

  Color get() {
    return bgColors[Random.secure().nextInt(bgColors.length)];
  }
}

这段代码实现了点击button1修改button2的颜色,点击button2修改parent的颜色,代码中的new关键字都省略了,这是dart2中的新特性。
从外部修改button2的颜色比较简单,只要在button1点击事件中修改传入button2的变量btnColor即可;
从button2点击修改父组件颜色,就需要用到回调,父控件构建button2的时候传入回调函数MyButton((c) => changeParentColor(c), btnColor),这里changeParentColor是作为一个对象之间传入子控件赋值给callback的,而子控件在onPressed: () => widget.callback(RandomColor().get()),这里设置了点击事件,点击时调用widget.callback即changeParentColor,以达到从内部向外部通信的目的,注意不能写成onPressed:widget.callback(RandomColor().get())

二、eventbus

先在pubspec.yaml里增加依赖

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  event_bus: ^1.0.1//增加依赖

dart文件中再导入包

import 'package:event_bus/event_bus.dart';

接下来就可以使用eventbus进行通信了,下面代码实现了点击button3可以修改button4的颜色,也就是点击的时发送一个事件,button4监听到该事件就改变自身颜色。

/**
 * 以下是用eventbus进行通信
 */

EventBus eventBus = new EventBus();

//新建修改颜色的事件
class ColorEvent{
  Color color;
  ColorEvent(this.color);
}

//button3
class MyButton3 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      //点击的时候发送改变颜色事件
      onPressed: () => eventBus.fire(ColorEvent(RandomColor().get())),
      child: Text('Button3,点击修改Button4颜色'),
    );
  }
}

//button4
class MyButton4 extends StatefulWidget {

  @override
  State createState() {
    return _MyButton4();
  }
}

class _MyButton4 extends State<MyButton4> {
  Color bgColor;

  @override
  void initState() {
    //注册eventBus事件,监听到变化的时候调用changeColor(color)
    eventBus.on<ColorEvent>().listen((ColorEvent data) => changeColor(data.color));
    super.initState();
  }

  changeColor(color){
    //若不对mounted进行判断,会报错 setState() called after dispose()
    if(mounted){
      setState(() {
        bgColor=color;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: ()=>{},//必须给onPressed一个空方法,不能是null,否则无法修改color属性
      child: Text('Button4'),
      color: bgColor,
    );
  }
}

eventbus的Git地址:https://github.com/marcojakob/dart-event-bus
详解可参考:https://cloud.tencent.com/developer/article/1338289

相关文章

  • 四、Flutter之组件间通信

    这里学了两种通信方式,一种是回调、另一种是借用第三方库event_bus,其他的还有GlobalKey、Value...

  • Flutter 与原生交互总结

    Flutter学习诀窍,Flutter一切皆组件! Android与Flutter之间的通信共有四种实现方式。 由...

  • Flutter与原生交互总结

    Flutter学习诀窍,Flutter一切皆组件! Android与Flutter之间的通信共有四种实现方式。 由...

  • 进程间通信,数据流传递(AIDL、Socket)

    进程间通信 Android 四大组件 Android 进程间通信可以通过Android 四大组件实现。 Activ...

  • React组件间通信

    组件间不同的嵌套关系,会导致不同的通信方式。常见的有:父组件向子组件通信、子组件向父组件通信、没有嵌套关系的组件之...

  • React组件间通信

    1. 组件间通信1.1.父组件向子组件通信1.2.子组件向父组件通信1.3.跨级组件间通信1.4.无嵌套关系组件间...

  • RN(四)--组件间通信

    谈组件通信前我们先了解一下组件的生命周期,这也是基础。 一、组件生命周期 这个图看上图挺乱,其实我们注意一下经常会...

  • vue.js系列三:组件间通信

    1.组件间通信基本原则 2.vue 组件间通信方式 2.1组件间通信 1: props(适用于父子组件传递属性) ...

  • vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法

    Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面分别介绍每种通信方式且会说...

  • react之组件通信

    需要组件之进行通信的几种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件通信 没有嵌套关系组件之间的通信 ...

网友评论

    本文标题:四、Flutter之组件间通信

    本文链接:https://www.haomeiwen.com/subject/wdkgyqtx.html