四、Futterのコンポーネント間通信

5076 ワード

ここでは二種類の通信方式を学びました。一つはコールバック、もう一つは第三者のライブラリイベントを借りることです。他にもGlobalKey、Value Notifier、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 {
  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: [
          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 {
  @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)];
  }
}
このコードはbutton 1をクリックしてbutton 2の色を修正して、button 2をクリックしてparentの色を修正して、コードの中のnewキーワードはすべて省略して、これはdart 2の中の新しい特性です。外部からbutton 2の色を修正するのは簡単です。button 1クリックイベントでbutton 2に入る変数btnColorを修正すればいいです。button 2から親コンポーネントの色を変更するには、チューニングが必要です。親コントロールがbutton 2を構築する際に、コールバック関数MyButton((c) => changeParentColor(c), btnColor),に着信しました。ここでchangePartColorはオブジェクト間に入ってきたサブコントロールの割り当て値がcalbackに与えられました。サブコントロールはonPressed: () => widget.callback(RandomColor().get()),にクリックイベントを設定しました。クリックする時にwidget.callbackを呼び出します。内部から外部への通信を目的として、onPressed:widget.callback(RandomColor().get())とは書
二、eventbus
まずpbspec.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//    
ダントファイルからカバンをインポートします。
import 'package:event_bus/event_bus.dart';
次はeventbusを使って通信できます。下のコードはbutton 3をクリックしてbutton 4の色を変更できます。つまりクリックした時にイベントを送ります。
/**
 *     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 {
  Color bgColor;

  @override
  void initState() {
    //  eventBus  ,          changeColor(color)
    eventBus.on().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