Flutter:将数据从 StatefulWidget child class 返回给 parent

Flutter: Get data back from StatefulWidget child class to parent

我是 Flutter 新手。

我在应用程序中有一个页面(Stateful Widget),其中一列有很多小部件。为了提高代码的可读性,我采用了一些小部件,并将它们制作成单独的 classes。例如,我将我的下拉菜单小部件制作成它唯一的 class,如下所示:

class DropDownMenuWidget extends StatefulWidget {


  
  DropDownMenuWidget({Key? key}) : super(key: key);

  @override
  _DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {



  String dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(
          color: Colors.black,
        fontSize: 20,

      ),
      underline: Container(
        height: 2,
        color: Colors.blue,
      ),
      onChanged: (String? newValue) {
        setState(() {
          dropdownValue = newValue!;
        });
      },
      items: MASLULIM
          .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

现在,在父 class 中,我这样显示小部件:

DropDownMenuWidget(),

但是,问题是,当用户单击某个项目时,我只能从 DropDownMenu class 中检索该值,并调用 setState() 方法。但是,我需要在父 class 中读取此值。我怎样才能到达那里?

谢谢

无需在 Widget 中创建 dropdownValue 变量,您可以在 ValueNotifier

的帮助下从父 Widget 获取它,如下所示
class DropDownMenuWidget extends StatefulWidget {
  ValueNotifier dropdownValueNotifier;
  DropDownMenuWidget(this.dropdownValueNotifier, {Key key}) : super(key: key);

  @override
  _DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}

class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: widget.dropdownValueNotifier,
      builder: (context, dropdownValue, _) {
        return DropdownButton<String>(

          value: dropdownValue,

          // ...

          onChanged: (String newValue) {
            // simply change the value. You dont need setState anymore
            widget.dropdownValueNotifier.value = newValue;
          },

          // ...
        );
      },
    );
  }
}

在父Widget中,创建变量并像这样传递它

ValueNotifier dropdownValueNotifier = ValueNotifier('One');

// ...

DropDownMenuWidget(dropdownValueNotifier),

在这种情况下,您可以使用typedef

首先在单独的 DrobDown 菜单中,您可以在 class 之外创建以下图标:

typedef OnItemSelectedDropDown = Function (String value);

现在你可以按如下方式应用这个东西:

class DropDownMenuWidget extends StatefulWidget {

   final OnItemSelectedDropDown onItemSelected ;

  DropDownMenuWidget({Key? key}) : super(key: key);

  @override
  _DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {



  String dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(
        color: Colors.black,
        fontSize: 20,

      ),
      underline: Container(
        height: 2,
        color: Colors.blue,
      ),
      onChanged: (String value) {
        //This line return Value
        widget.onItemSelected.call(value);
      },
      items: MASLULIM
          .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

调用classDropDownMenuWidget时,在另一屏调用如下:

String dropdownValue ;
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('DropDown Page'),
      ),
      body: Center(
        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'New Value DropDown : $dropdownValue',
            ),
            DropDownMenuWidget(
                onItemSelected :(newValue){
                  setState(() {
                    dropdownValue = newValue ;
                  });
                }
            ),
          ],
        ),
      ),
    );
  }