【问题标题】:How to implement dropdownbutton into a function in flutter如何在flutter中将下拉按钮实现为函数
【发布时间】:2022-01-20 07:04:01
【问题描述】:

我正在处理一个公司项目。但我不能简单地了解如何将基本下拉按钮实现到函数中,但我似乎无法在下拉函数中更改值你认为我做错了什么这是我的代码:

Widget buildDropdownField({
  required String dropdownHeader,
  required String dropdownValue,
}) {
  return Column(
    children: <Widget>[
      Text(dropdownHeader),
      const SizedBox(
        height: 10,
      ),
      //dropdownField
      DropdownButton<String>(
        value: dropdownValue,
        icon: const Icon(Icons.arrow_downward),
        elevation: 16,
        style: const TextStyle(color: Colors.deepPurple),
        underline: Container(
          height: 2,
          color: Colors.deepPurpleAccent,
        ),
        onChanged: (String? newValue) {
          setState(() {
            dropdownValue = newValue!;
          });
        },
        items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz']
            .map<DropdownMenuItem<String>>((String value) {
          return DropdownMenuItem<String>(
            value: value,
            child: Text(value),
          );
        }).toList(),
      )
    ],
  );
}

【问题讨论】:

    标签: flutter mobile


    【解决方案1】:

    用 StatefulBuilder 包裹它会工作。

    Widget buildDropdownField(
          {required String dropdownHeader, required String dropdownValue}) {
        return Column(
          children: <Widget>[
            Text(dropdownHeader),
            const SizedBox(
              height: 10,
            ),
            StatefulBuilder(
              builder: (_, setDropState) {
                return DropdownButton<String>(
                  value: dropdownValue,
                  icon: const Icon(Icons.arrow_downward),
                  elevation: 16,
                  style: const TextStyle(color: Colors.deepPurple),
                  underline: Container(
                    height: 2,
                    color: Colors.deepPurpleAccent,
                  ),
                  onChanged: (String? newValue) {
                    setDropState(() {
                      dropdownValue = newValue!;
                    });
                  },
                  items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz']
                      .map<DropdownMenuItem<String>>((String value) {
                    return DropdownMenuItem<String>(
                      value: value,
                      child: Text(value),
                    );
                  }).toList(),
                );
              },
            )
          ],
        );
      }
    

    【讨论】:

      【解决方案2】:

      试试下面的代码希望它对你有帮助。使用 StatefulBuilder 参考here

      您的下拉功能:

      buildDropdownField({
        required String dropdownHeader,
        required String dropdownValue,
      }) {
        return Column(
          children: <Widget>[
            Text(dropdownHeader),
            const SizedBox(
              height: 10,
            ),
            //dropdownField
            StatefulBuilder(builder: (context, StateSetter setState) {
              return DropdownButton<String>(
                value: dropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    dropdownValue = newValue!;
                  });
                },
                items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz']
                    .map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
              );
            })
          ],
        );
      }
      

      您的小部件:

      buildDropdownField(
            dropdownHeader: 'dropdownHeader',
            dropdownValue: '-',
          ),
      

      结果->

      选择后的结果->

      【讨论】:

      • 它确实可以工作,但是一旦我使用步进器小部件进入下一个屏幕,它的状态就会重置,我希望能够存储我选择的值,让它在选择后保持不变。
      【解决方案3】:

      首先,您不应该使用新值更新参数。它确实更新了参数,但函数仍会从它的调用中获取值。

      我不知道buildDropdownField 函数是否在一个类中,但没关系,我将为这两种情况提供解决方案。

      班级内

      您需要在函数之外的类中创建一个变量。

      class MyHomePage extends StatefulWidget {
        const MyHomePage({Key? key, required this.title}) : super(key: key);
      
        final String title;
      
        @override
        State<MyHomePage> createState() => _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
        String _dropDownValue = '-';
      
        Widget buildDropdownField({required String dropdownHeader}) {
          return Column(
            children: <Widget>[
              Text(dropdownHeader),
              const SizedBox(
                height: 10,
              ),
              //dropdownField
              DropdownButton<String>(
                value: _dropDownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
                onChanged: (String? newValue) {
                  setState(() {
                    _dropDownValue = newValue!;
                  });
                },
                items: <String>['-', 'Geçti', 'Kaldı', 
        'Belirsiz'].map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
              )
            ],
          );
        }
      }
      

      课外

      您需要将其转换为 Stateful Widget 才能更改下拉文本。一旦下拉列表是一个有状态的小部件,您可以使用上面的解决方案或回调来对父类进行更改。

      class MyHomePage extends StatefulWidget {
        const MyHomePage({Key? key, required this.title}) : super(key: key);
      
        final String title;
      
        @override
        State<MyHomePage> createState() => _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
        String _dropDownValue = '-';
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Center(
              child: DropDownWidget(
                dropdownHeader: 'Name',
                dropdownValue: _dropDownValue,
                onChanged: (String? newValue) {
                  setState(() {
                    _dropDownValue = newValue!;
                  });
                },
              ),
            ),
          );
        }
      }
      
      class DropDownWidget extends StatefulWidget {
        final String dropdownHeader;
        final String dropdownValue;
        final Function(String?)? onChanged;
      
        DropDownWidget({required this.dropdownHeader, required this.dropdownValue, this.onChanged, Key? key}) : super(key: key);
      
        @override
        _DropDownWidgetState createState() => _DropDownWidgetState();
      }
      
      class _DropDownWidgetState extends State<DropDownWidget> {
        @override
        Widget build(BuildContext context) {
          return Column(
            children: <Widget>[
              Text(widget.dropdownHeader),
              const SizedBox(
                height: 10,
              ),
              //dropdownField
              DropdownButton<String>(
                value: widget.dropdownValue,
                icon: const Icon(Icons.arrow_downward),
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
                onChanged: widget.onChanged,
                items: <String>['-', 'Geçti', 'Kaldı', 'Belirsiz'].map<DropdownMenuItem<String>>((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
              )
            ],
          );
        }
      }
      
      

      【讨论】:

      • 谈论类内部的情况:我希望将下拉值作为参数给出。我怎样才能做到这一点
      • 对于这种情况,您需要一个回调参数 (onChanged) 来更新提供给 dropdownValue 参数的值。回调的实现可以参考“类外”解决方案,类似。
      猜你喜欢
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      相关资源
      最近更新 更多