美文网首页
Flutter 组件间通信

Flutter 组件间通信

作者: 简单快乐6 | 来源:发表于2023-07-25 16:03 被阅读0次

    通信实现方式

    回调通信

    需求“点击子组件,修改父组件的背景颜色与子组件背景颜色一致”
    使用场景:一般用于子组件对父组件传值。

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    ///使用场景:一般用于子组件对父组件传值。
    class ParentWidget extends StatefulWidget {
      final String? title;
    
      ParentWidget({Key? key,this.title}):super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return ParentWidgetState();
      }
    
    }
    
    class ParentWidgetState extends State<ParentWidget>{
    
      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: (){
    
              },
              child: new Container(
              width: 300,
              height: 300,
              color: containerBg,
              alignment: Alignment.center,
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  childrenA(childrenABallback: changeBackgroundColor,),
                  childrenB(childrenBBallback: changeBackgroundColor,),
                ],
              ),
            ),
            ),
          ),
    
        );
      }
    
    }
    
    
    ///自组件 A
    class childrenA extends StatelessWidget {
    
      final ValueChanged<Color>? childrenABallback;
    
      childrenA({Key? key,this.childrenABallback});
    
      @override
      Widget build(BuildContext context) {
        return new GestureDetector(
          onTap: (){
            childrenABallback!(Colors.green);
          },
          child: new Container(
            width: 80,
            height: 80,
            color: Colors.green,
            child: new Text("ChildrenA"),
          ),
        );
      }
    
    }
    
    
    
    ///自组件 A
    class childrenB extends StatelessWidget {
    
      final ValueChanged<Color>? childrenBBallback;
    
      childrenB({Key? key,this.childrenBBallback});
    
      @override
      Widget build(BuildContext context) {
        return new GestureDetector(
          onTap: (){
            childrenBBallback!(Colors.red);
          },
          child: new Container(
            width: 80,
            height: 80,
            color: Colors.red,
            child: new Text("ChildrenB"),
          ),
        );
      }
    
    }
    
    
    2941690359496_.pic.jpg

    InheritedWidget 数据共享

    场景:业务开发中经常会碰到这样的情况,多个Widget需要同步同一份全局数据,比如点赞数、评论数、夜间模式等等。
    使用场景 一般用于父组件对子组件的跨组件传值。

    //模型数据
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    ///一般用于父组件对子组件的跨组件传值。
    class InheritedTestModel {
      final int count;
      const InheritedTestModel(this.count);
    }
    
    //哨所(自定义InheritedWidget类)
    class  InheritedContext extends InheritedWidget {
    
      //变量
      final InheritedTestModel inheritedTestModel;
      final Function() increment;
      final Function() reduce;
    
      InheritedContext({Key? key,
        required this.inheritedTestModel,
        required this.increment,
        required this.reduce,
        required Widget child,
      }) : super(key:key,child: child);
    
      //定义一个便捷方法,方便子树中的widget获取共享数据
      static InheritedContext? of(BuildContext context) {
        return context.dependOnInheritedWidgetOfExactType<InheritedContext>();
      }
    
      //是否重建取决于Widget组件是否相同
      @override
      bool updateShouldNotify(InheritedContext oldWidget) {
        return  inheritedTestModel != oldWidget.inheritedTestModel;
      }
    
    }
    
    class TestWidgetA extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print("TestWidgetA build");
        var of = InheritedContext.of(context);
        return new Padding(
            padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
            child: new RaisedButton(
              textColor: Colors.black,
                child: Text("+"),
                onPressed: of?.increment
            ),
        );
      }
    }
    
    class TestWidgetB extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print("TestWidgetB build");
        var of = InheritedContext.of(context);
        return new Padding(
          padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
          child: new RaisedButton(
              textColor: Colors.black,
              child: Text("-"),
              onPressed: of?.reduce
          ),
        );
      }
    }
    
    class TestWidgetC extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print("TestWidgetC build");
        var of = InheritedContext.of(context);
        var model = of?.inheritedTestModel;
        return new Padding(
          padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
          child: new RaisedButton(
              textColor: Colors.black,
              child: Text('${model?.count}'),
              onPressed: (){
    
              }
          ),
        );
      }
    }
    
    class InheritedWidgetTestContainer extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return new InheritedWidgetTestContainerState();
      }
    }
    class InheritedWidgetTestContainerState extends State<InheritedWidgetTestContainer> {
    
      InheritedTestModel? _inheritedTestModel;
    
      _initData(){
        _inheritedTestModel = new InheritedTestModel(0);
      }
    
      @override
      void initState() {
        _initData();
        super.initState();
      }
    
      _incrementCount(){
        setState(() {
          _inheritedTestModel = new InheritedTestModel(1 + (_inheritedTestModel?.count??0));
        });
      }
    
      _reduceCount(){
        setState(() {
          _inheritedTestModel = new InheritedTestModel((_inheritedTestModel?.count??0) - 1);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return InheritedContext(
            inheritedTestModel: _inheritedTestModel!,
            increment: _incrementCount,
            reduce: _reduceCount,
            child: Scaffold(
              appBar: AppBar(
                title: Text('inheritedWidgetTest'),
              ),
              body: new Center(
                child: Column(
                  children: [
                    TestWidgetA(),
                    TestWidgetB(),
                    TestWidgetC()
                  ],
                ),
              ),
            ));
      }
    
    }
    
    2951690359496_.pic.jpg

    Global Key通信

    GlobalKey能够跨Widget访问状态。
    需求“点击A子组件,修改B子组件的背景颜色为指定的‘蓝色”
    使用场景:一般用于跨组件访问状态

    //父组件
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    ///一般用于跨组件访问状态
    class ParentGolablWidget extends  StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return new ParentGolablWidgetState();
      }
    }
    GlobalKey<SubWidgetAState> subAkey = GlobalKey();
    GlobalKey<SubWidgetBState> subBkey = GlobalKey();
    class ParentGolablWidgetState extends State<ParentGolablWidget>{
    
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('组件化'),
          ),
          body: Center(
            child: Container(
              color: Colors.grey,
              width: 200,
              height: 200,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  SubWidgetA(key: subAkey),
                  SubWidgetB(key: subBkey),
                ],
              ),
            ),
          ),
        );
      }
    
    }
    
    
    class SubWidgetA extends StatefulWidget{
    
      SubWidgetA({Key? key}):super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return SubWidgetAState();
      }
    
    
    }
    
    class SubWidgetAState extends State<SubWidgetA>{
    
      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: Text('subWidgetA'),
          ),
        );
      }
    }
    
    //子组件B
    class SubWidgetB extends StatefulWidget {
      SubWidgetB({Key? key}):super(key:key);
      @override
      State<StatefulWidget> createState() {
        return new SubWidgetBState();
      }
    }
    
    class SubWidgetBState extends State<SubWidgetB>{
    
      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: Text('subWidgetB'),
          ),
        );
      }
    }
    
    
    2961690359497_.pic.jpg

    ValueNotifier通信

    ValueNotifier是一个包含单个值的变更通知器,当它的值改变的时候,会通知它的监听

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class ValueNotifierData extends ValueNotifier<String>{
      ValueNotifierData(super.value);
    }
    
    class _WidgetOne extends StatefulWidget {
      ValueNotifierData? data;
      _WidgetOne({this.data});
    
    
      @override
      State<StatefulWidget> createState() {
        return _WidgetOneState();
      }
    }
    
    class _WidgetOneState extends State<_WidgetOne>{
    
      String? info = null;
    
      @override
      void initState() {
        super.initState();
        widget.data?.addListener(_handleValueChange);
        info = 'Initial message: ${widget.data?.value}';
      }
    
      @override
      void dispose() {
        widget.data?.removeListener(_handleValueChange);
        super.dispose();
      }
    
      void _handleValueChange(){
        setState(() {
          info = 'Message changed to: ${widget.data?.value}' ;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        print("_WidgetOneState build()");
        return Container(
          child: Center(
            child: Text(info??''),
          ),
        );
      }
    
    }
    
    class ParentValueNotifierCommunication extends StatelessWidget {
    
    
      @override
      Widget 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';
            },
          ),
        );
      }
    
    
    
    2971690359498_.pic.jpg

    第三方插件

    event_bus来实现传值

    引入插件
    import 'package:event_bus/event_bus.dart';
    新建消息监测类
    import 'package:event_bus/event_bus.dart';
      EventBus eventBus = new EventBus();
      class TransEvent{
       String text;
       TransEvent(this.text);
      }
    监测类变化
    eventBus.on<TransEvent>().listen((TransEvent data) => show(data.text));
    void show(String val) {
     setState(() {
      data = val;
     });
    }
    触发消息变化
    eventBus.fire(new TransEvent('$inputText'));
    

    项目地址
    https://gitee.com/shiming_bai/textfluttertimer

    相关文章

      网友评论

          本文标题:Flutter 组件间通信

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