あるステートフルウィジェットから別のステートフルウィジェットのメソッドを呼び出す - Flutter Ask Question

あるステートフルウィジェットから別のステートフルウィジェットのメソッドを呼び出す - Flutter Ask Question

私はステートフルウィジェットを持っていて、そのステートフルウィジェットの中に、拡張するクラスの下のいくつかの関数を持っています。State<MusicPlayer>

ファイルlib\main.dart

次のような単純な関数を取ります

class MyAppState extends State<MyApp>{
...
void printSample (){
  print("Sample text");
}
...

この関数はメインクラス内のステートフルウィジェット内にあります。

別のファイルがありますlib\MyApplication.dart

このファイルにはステートフル ウィジェットも含まれていますが、printSample()ここで関数を呼び出すことができるように何かできますか。

class MyApplicationState extends State<MyApplication>{
...
@override
  Widget build(BuildContext context) {
    return new FlatButton(
      child: new Text("Print Sample Text"),
      onPressed :(){
       // i want to cal the function here how is it possible to call the 
       // function 
       // printSample()  from here??  
      }
    );
  }
}

ベストアンサー1

親の関数を呼び出すには、コールバック パターンを使用できます。この例では、関数 ( onColorSelect) が子に渡されます。子はボタンが押されたときに関数を呼び出します。

import 'package:flutter/material.dart';

class Parent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ParentState();
  }
}

class ParentState extends State<Parent> {
  Color selectedColor = Colors.grey;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(
          color: selectedColor,
          height: 200.0,
        ),
        ColorPicker(
          onColorSelect: (Color color) {
            setState(() {
              selectedColor = color;
            });
          },
        )
      ],
    );
  }
}

class ColorPicker extends StatelessWidget {
  const ColorPicker({this.onColorSelect});

  final ColorCallback onColorSelect;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        RaisedButton(
          child: Text('red'),
          color: Colors.red,
          onPressed: () {
            onColorSelect(Colors.red);
          },
        ),
        RaisedButton(
          child: Text('green'),
          color: Colors.green,
          onPressed: () {
            onColorSelect(Colors.green);
          },
        ),
        RaisedButton(
          child: Text('blue'),
          color: Colors.blue,
          onPressed: () {
            onColorSelect(Colors.blue);
          },
        )
      ],
    );
  }
}

typedef ColorCallback = void Function(Color color);

ボタンやフォーム フィールドなどの内部 Flutter ウィジェットは、まったく同じパターンを使用します。引数なしで関数を呼び出すだけの場合は、VoidCallback代わりに独自のコールバック タイプを定義するタイプを使用できます。


上位の親に通知したい場合は、階層レベルごとにこのパターンを繰り返すだけです。

class ColorPickerWrapper extends StatelessWidget {
  const ColorPickerWrapper({this.onColorSelect});
  
  final ColorCallback onColorSelect;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20.0),
      child: ColorPicker(onColorSelect: onColorSelect),
    )
  }
}

Flutter では、親ウィジェットから子ウィジェットのメソッドを呼び出すことは推奨されていません。代わりに、Flutter では、子ウィジェットの状態をコンストラクター パラメーターとして渡すことが推奨されています。子ウィジェットのメソッドを呼び出す代わりに、setState親ウィジェットを呼び出して子ウィジェットを更新するだけです。


代替アプローチの 1 つは、controllerFlutter のクラス ( ScrollController、、AnimationController...) です。これらもコンストラクター パラメーターとして子に渡され、setState親を呼び出さずに子の状態を制御するメソッドが含まれています。例:

scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);

子はこれらの変更を監視して内部状態を更新する必要があります。もちろん、独自のコントローラー クラスを実装することもできます。必要な場合は、Flutter のソース コードを参照して、その仕組みを理解することをお勧めします。


フューチャーとストリームは状態を渡すための別の代替手段であり、子の関数を呼び出すためにも使用できます。

しかし、私はそれを本当にお勧めしません。子ウィジェットのメソッドを呼び出す必要がある場合、アプリケーション アーキテクチャに欠陥がある可能性が非常に高くなります。状態を共通の祖先まで移動してみてください。

おすすめ記事