【问题标题】:Flutter: Get data back from StatefulWidget child class to parentFlutter:将数据从 StatefulWidget 子类返回给父类
【发布时间】:2021-04-28 00:37:57
【问题描述】:

我是 Flutter 新手。

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

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(),
    );
  }
}

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

DropDownMenuWidget(),

但是,问题是,当用户单击一个项目时,我只能从 DropDownMenu 类中检索该值,然后调用 setState() 方法。但是,我需要在父类中读取这个值。我怎样才能得到它?

谢谢

【问题讨论】:

    标签: flutter dart flutter-widget


    【解决方案1】:

    您可以在 ValueNotifier 的帮助下从父 Widget 获取它,而不是在 Widget 中创建 dropdownValue 变量

    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),
    

    【讨论】:

    • 这就是我如何将变量传递给小部件,但是当用户选择一个变量时,我如何将它返回给父级?谢谢
    • 首先在父控件中创建变量,然后通过参数传递给子控件。正如你在上面看到的那样
    • 我明白你在说什么,但是用户会在小部件中选择不同的值,并且需要父级读取该值
    • 一个更好的方法是使用ValueNotifier
    • 检查新解决方案
    【解决方案2】:

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

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

    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(),
        );
      }
    }
    

    调用DropDownMenuWidget类时,在另一个屏幕上调用如下:

    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 ;
                      });
                    }
                ),
              ],
            ),
          ),
        );
      }
    

    【讨论】:

      猜你喜欢
      • 2014-04-01
      • 2022-11-17
      • 2019-05-10
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多