【问题标题】:Flutter Dynamic DropdownFormField value not getting updated with the indexFlutter Dynamic DropdownFormField 值未随索引更新
【发布时间】:2021-02-04 04:08:23
【问题描述】:

我是 Flutter 的新手,正在尝试使用 Dynamic FormField 构建应用程序,问题是 dropdownformfield 值没有随索引更新。但是,它适用于 textformfield 但不适用于 Dropdownformfield

当您按下 + 按钮时,会出现一个新行,但如果您查看下拉表单字段,则该值会变为空白并且不会随行更新。 这是代码。

class DynamicWidgets extends StatefulWidget {
  @override
  _DynamicWidgetState createState() => _DynamicWidgetState();

  }


class _DynamicWidgetState extends State<DynamicWidgets> {
  final _formKey = GlobalKey<FormState>();
  TextEditingController _nameController;
  static List<String> dropdowndata=[null];
  static List<String> descriotiondata=[null];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _nameController = TextEditingController();
    _nameController.text = "XR";
  }

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Form(
      key: _formKey,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              padding: const EdgeInsets.only(right: 32.0),
              child: TextFormField(
                controller: _nameController,
                decoration: InputDecoration(hintText: 'Modality Name'),
                validator: (v) {
                  if (v.trim().isEmpty) return 'Please enter something';
                  return null;
                },
              ),
            ),
            Text("Add More Study"),
            SizedBox(
              height: 5,
            ),
            ..._getFields(),
            SizedBox(
              height: 10,
            ),
            FlatButton(
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                  debugPrint("Widget1 Key data: ${dropdowndata.toString()}");
                  debugPrint("Widget2 Key data: ${descriotiondata.toString()}");
                }
              },
              child: Text(
                'Submit',
                style: TextStyle(color: Colors.white),
              ),
              color: Colors.green,
            ),
          ],
        ),
      ),
    );
    throw UnimplementedError();
  }

  List<Widget> _getFields() {
    List<Widget> friendsTextFields = [];
    for (int i = 0; i < dropdowndata.length; i++) {
      friendsTextFields.add(Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: Row(
          children: [
            Expanded(child: DynamicFields(i)),
            SizedBox(
              width: 16,
            ),
            // we need add button at last friends row
            _addRemoveButton(i == dropdowndata.length - 1, i),
          ],
        ),
      ));
    }
    return friendsTextFields;
  }

  Widget _addRemoveButton(bool add, int index) {
    return InkWell(
      onTap: () {
        if (add) {
          // add new text-fields at the top of all friends textfields
          dropdowndata.insert(0, null);
          descriotiondata.insert(0, null);
        } else {
          dropdowndata.removeAt(index);
          descriotiondata.removeAt(index);
        }
        setState(() {});
      },
      child: Container(
        width: 30,
        height: 30,
        decoration: BoxDecoration(
          color: (add) ? Colors.green : Colors.red,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Icon(
          (add) ? Icons.add : Icons.remove,
          color: Colors.white,
        ),
      ),
    );
  }
}


class DynamicFields extends StatefulWidget {
  final int index;
  DynamicFields(this.index);
  @override
  _DynamicFieldsState createState() => _DynamicFieldsState();
}

class _DynamicFieldsState extends State<DynamicFields>{
  TextEditingController _descriptionController;
    var _selectedValue;
    var _dropdownvalue;
  String _myActivity;
  String _myActivityResult;
  static var _studynames = ["CT-62", "CT-53","CT-54","CT-50"];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._descriptionController=TextEditingController();

  }
  @override
  void dispose() {
    _descriptionController.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _descriptionController.text = _DynamicWidgetState.descriotiondata[widget.index] ?? '';
      _selectedValue=_DynamicWidgetState.dropdowndata[widget.index] ?? '';
    });
    // TODO: implement build
    return Row(
      children: [
        Flexible(
          flex: 1,
          child: Container(
            margin: EdgeInsets.all(5.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(5.0),
              border: Border.all(
                  color: Colors.blueGrey, style: BorderStyle.solid, width: 0.80),
            ),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Material(
                shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
                elevation: 0.0,
                child: ListTile(
                  title: DropdownButton(
                    items: _studynames.map((String dropdownitem) {
                      return DropdownMenuItem<String>(
                        value: dropdownitem,
                        child: Text(
                          dropdownitem,
                          style: TextStyle(color: Color(0xFF4BC1FF)),
                        ),
                      );
                    }).toList(),
                    underline: Container(
                      height: 0,
                    ),
                    value: _dropdownvalue,
                    onChanged: (valueSelected) {
                      setState(() {
                        debugPrint("$valueSelected value selected");
                        _dropdownvalue = valueSelected;
                        _DynamicWidgetState.dropdowndata[widget.index] = valueSelected;

                      });
                    },
                  ),
                ),
              ),
            ),
          )
          ),

        SizedBox(width: 10),
        Flexible(
          flex: 1,
          child:  TextFormField(
            controller: _descriptionController,
            onChanged: (v) => _DynamicWidgetState.descriotiondata[widget.index] = v,
            decoration: InputDecoration(
                hintText: 'Study Description'
            ),
            validator: (v){
              if(v.trim().isEmpty) return 'Please enter Study Description';
              return null;
            },
          ),
        )
      ],
    );
    throw UnimplementedError();
  }

}

【问题讨论】:

    标签: flutter dart flutter-layout flutter-widget


    【解决方案1】:

    在“_DynamicFieldsState”下的字段中获取“下拉”值时,您没有使用您创建的列表数据。因此,您的应用程序不知道它将在这些领域获得的价值。查看我是否只是更改了“_DynamicFieldsState”字段中的一些值。

    import 'package:flutter/material.dart';
    
    class DynamicWidgets extends StatefulWidget {
      @override
      _DynamicWidgetState createState() => _DynamicWidgetState();
    
    }
    
    
    class _DynamicWidgetState extends State<DynamicWidgets> {
      final _formKey = GlobalKey<FormState>();
      TextEditingController _nameController;
      static List<String> dropdowndata=[null];
      static List<String> descriotiondata=[null];
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        _nameController = TextEditingController();
        _nameController.text = "XR";
      }
    
      @override
      void dispose() {
        _nameController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          resizeToAvoidBottomPadding: false,
    
          body: Form(
            key: _formKey,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.only(right: 32.0),
                    child: TextFormField(
                      controller: _nameController,
                      decoration: InputDecoration(hintText: 'Modality Name'),
                      validator: (v) {
                        if (v.trim().isEmpty) return 'Please enter something';
                        return null;
                      },
                    ),
                  ),
                  Text("Add More Study"),
                  SizedBox(
                    height: 5,
                  ),
                  ..._getFields(),
                  SizedBox(
                    height: 10,
                  ),
                  FlatButton(
                    onPressed: () {
                      if (_formKey.currentState.validate()) {
                        _formKey.currentState.save();
                        debugPrint("Widget1 Key data: ${dropdowndata.toString()}");
                        debugPrint("Widget2 Key data: ${descriotiondata.toString()}");
                      }
                    },
                    child: Text(
                      'Submit',
                      style: TextStyle(color: Colors.white),
                    ),
                    color: Colors.green,
                  ),
                ],
              ),
            ),
          ),
        );
        throw UnimplementedError();
      }
    
      List<Widget> _getFields() {
        List<Widget> friendsTextFields = [];
        for (int i = 0; i < dropdowndata.length; i++) {
          friendsTextFields.add(Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: Row(
              children: [
                Expanded(child: DynamicFields(i)),
                SizedBox(
                  width: 16,
                ),
                // we need add button at last friends row
                _addRemoveButton(true, i),
              ],
            ),
          ));
        }
        return friendsTextFields;
      }
    
      Widget _addRemoveButton(bool add, int index) {
        print('index:' + index.toString());
        return InkWell(
          onTap: () {
            if (add) {
              // add new text-fields at the top of all friends textfields
              dropdowndata.insert(0, null);
              descriotiondata.insert(0, null);
            } else {
              dropdowndata.removeAt(index);
              descriotiondata.removeAt(index);
            }
            setState(() {});
          },
          child: Container(
            width: 30,
            height: 30,
            decoration: BoxDecoration(
              color: (add) ? Colors.green : Colors.red,
              borderRadius: BorderRadius.circular(20),
            ),
            child: Icon(
              (add) ? Icons.add : Icons.remove,
              color: Colors.white,
            ),
          ),
        );
      }
    }
    
    
    class DynamicFields extends StatefulWidget {
      final int index;
      DynamicFields(this.index);
      @override
      _DynamicFieldsState createState() => _DynamicFieldsState();
    }
    
    class _DynamicFieldsState extends State<DynamicFields>{
      TextEditingController _descriptionController;
      var _selectedValue;
      var _dropdownvalue;
      String _myActivity;
      String _myActivityResult;
      static var _studynames = ["CT-62", "CT-53","CT-54","CT-50"];
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        this._descriptionController=TextEditingController();
    
      }
      @override
      void dispose() {
        _descriptionController.dispose();
    
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _descriptionController.text = _DynamicWidgetState.descriotiondata[widget.index] ?? '';
          _selectedValue=_DynamicWidgetState.dropdowndata[widget.index] ?? '';
        });
        // TODO: implement build
        return Row(
          children: [
            Flexible(
                flex: 1,
                child: Container(
                  margin: EdgeInsets.all(5.0),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(5.0),
                    border: Border.all(
                        color: Colors.blueGrey, style: BorderStyle.solid, width: 0.80),
                  ),
                  child: Padding(
                    padding: EdgeInsets.all(2.0),
                    child: Material(
                      shape:
                      RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
                      elevation: 0.0,
                      child: ListTile(
                        title: DropdownButton(
                          items: _studynames.map((String dropdownitem) {
                            return DropdownMenuItem<String>(
                              value: dropdownitem,
                              child: Text(
                                dropdownitem,
                                style: TextStyle(color: Color(0xFF4BC1FF)),
                              ),
                            );
                          }).toList(),
                          underline: Container(
                            height: 0,
                          ),
                          value: _DynamicWidgetState.dropdowndata[widget.index], // Here
                          onChanged: (valueSelected) {
                            setState(() {
                              debugPrint("$valueSelected value selected");
                              _dropdownvalue = _DynamicWidgetState.dropdowndata[widget.index]; // Here
                              _DynamicWidgetState.dropdowndata[widget.index] = valueSelected;
    
                            });
                          },
                        ),
                      ),
                    ),
                  ),
                )
            ),
    
            SizedBox(width: 10),
            Flexible(
              flex: 1,
              child:  TextFormField(
                controller: _descriptionController,
                onChanged: (v) => _DynamicWidgetState.descriotiondata[widget.index] = v,
                decoration: InputDecoration(
                    hintText: 'Study Description'
                ),
                validator: (v){
                  if(v.trim().isEmpty) return 'Please enter Study Description';
                  return null;
                },
              ),
            )
          ],
        );
        throw UnimplementedError();
      }
    
    }
    

    【讨论】:

    • 非常感谢!!有没有一种方法可以在下拉值更改时重新调用 Dynamic 类的构造函数?
    猜你喜欢
    • 1970-01-01
    • 2020-06-01
    • 2022-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 2020-07-26
    • 1970-01-01
    相关资源
    最近更新 更多