zoukankan      html  css  js  c++  java
  • 【Flutter学习】组件通信(父子、兄弟)

    一,概述 

       flutter一个重要的特性就是组件化。组件分为两种状态,一种是StatefulWidget有状态组件,一种是StatelessWidget无状态组件。 无状态组件不能更新状态,有状态组件具有类似刷新的机制,可更改状态。
      功能模块都可以通过继承两种状态组件实现功能模块封装。组件间通信,一般存在一下两种关系。

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

    二, 通信实现方式

    • 回调通信
      • 需求“点击子组件,修改父组件的背景颜色与子组件背景颜色一致”
      • 代码实现
        //父组件
        
        class ParentWidget extends StatefulWidget {
          final String title;
          ParentWidget({Key key,this.title}):super(key:key);
        
          @override
          State<StatefulWidget> createState() {
            return new 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: (){ changeBackgroundColor(Colors.orange); }, child: new Container( 300, height: 300, color: containerBg, alignment: Alignment.center, child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ new childrenA(childrenACallBack: changeBackgroundColor), new childrenB(childrenBCallBack: changeBackgroundColor), ], ), ), ) ), ); } } //子组件(组件A) class childrenA extends StatelessWidget {
        //定义接收父类回调函数的指针
        final ValueChanged<Color> childrenACallBack;
          childrenA({Key key,this.childrenACallBack}):super(key:key);
          @override
          Widget build(BuildContext context) {
            return new GestureDetector(
              onTap: (){
           //调用回调函数传值 childrenACallBack(Colors.green); }, child:
        new Container( 80, height: 80, color: Colors.green, child: new Text('ChildrenA'), ), ); } } //子组件(组件B) class childrenB extends StatelessWidget { final ValueChanged<Color> childrenBCallBack; childrenB({Key key,this.childrenBCallBack}):super(key:key); @override Widget build(BuildContext context) { return new GestureDetector( onTap:(){ childrenBCallBack(Colors.red); }, child: new Container( 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<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(_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: <Widget>[
                      new TestWidgetA(),
                      new TestWidgetB(),
                      new TestWidgetC(),
                    ],
                 ),
                )
              ),
            );
          }
        }
      • 功能实现
         
      • 使用场景
        一般用于父组件对子组件的跨组件传值。

    • Global Key通信
      GlobalKey能够跨Widget访问状态。
      • 需求“点击A子组件,修改B子组件的背景颜色为指定的‘蓝色”
      • 代码实现
        //父组件
        class ParentWidget extends  StatefulWidget {
          @override
          State<StatefulWidget> createState() {
            return new ParentWidgetState();
          }
        }
        
        class ParentWidgetState extends State<ParentWidget> {
          @override
          Widget build(BuildContext context) {
          
            return new Scaffold(
              appBar: new AppBar(
                title:  new Text('组件化'),
              ),
              body: new Center(
                child: new Container(
                  color: Colors.grey,
                   200,
                  height: 200,
                  child: new Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      new SubWidgetA(key: subAkey),
                      new SubWidgetB(key: subBkey)
                    ],
                  ),
                ),
              ),
            );
          }
        }
        
        
        //子组件A
        
        class SubWidgetA extends StatefulWidget {
          SubWidgetA({Key key}):super(key:key);
         @override
          State<StatefulWidget> createState() {
            return new 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(
               80,
              height: 80,
              color:_backgroundColors,
              alignment: Alignment.center,
              child: new Text('SubWidgetA'),
            ),
            );
          }
        }
        
        
        
        //子组件B
        class SubWidgetB extends StatefulWidget {
          SubWidgetB({Key key}):super(key:key);
           @override
          State<StatefulWidget> createState() {
            // TODO: implement 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(
               80,
              height: 80,
              color: _backgroundColors,
              alignment: Alignment.center,
              child: new Text('SubWidgetB'),
            ),
            );
          }
        }
      • 功能实现
      • 使用场景:一般用于跨组件访问状态
    • ValueNotifier通信 

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

      1. 定义ValueNotifierData类,继承ValueNotifier
        class ValueNotifierData extends ValueNotifier<String> {
          ValueNotifierData(value) : super(value);
        }
      1. 定义_WidgetOne,包含一个ValueNotifierData的实例。
        class _WidgetOne extends StatefulWidget {
          _WidgetOne({this.data});
          final ValueNotifierData data;
          @override
          _WidgetOneState createState() => _WidgetOneState();
        }
      1. _WidgetOneState中给ValueNotifierData实例添加监听。
        @override
        initState() {
          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的更新。
        @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';
            }),
          );
        }
    • 第三方插件
        在这里运用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<TransEvent>().listen((TransEvent data) => show(data.text));
            void show(String val) {
             setState(() {
              data = val;
             });
            }
          • 触发消息变化

            eventBus.fire(new TransEvent('$inputText'));
        • 使用场景:这样我们就可以根据这些来实现组件之间的传值。
  • 相关阅读:
    METHODS OF AND APPARATUS FOR USING TEXTURES IN GRAPHICS PROCESSING SYSTEMS
    Display controller
    Graphics processing architecture employing a unified shader
    Graphics-Processing Architecture Based on Approximate Rendering
    Architectures for concurrent graphics processing operations
    Procedural graphics architectures and techniques
    DYNAMIC CONTEXT SWITCHING BETWEEN ARCHITECTURALLY DISTINCT GRAPHICS PROCESSORS
    Thermal zone monitoring in an electronic device
    System and method for dynamically adjusting to CPU performance changes
    Framework for Graphics Animation and Compositing Operations
  • 原文地址:https://www.cnblogs.com/lxlx1798/p/11172246.html
Copyright © 2011-2022 走看看