Получить значения из динамически сгенерированного виджета в flutter и добавить выпадающий список к сгенерированному виджету

#flutter

#flutter

Вопрос:

Привет, у меня есть программа, которая добавляет новый виджет в столбец при нажатии кнопки, когда я запускаю это, она должна создать выпадающий список и текстовое поле внутри него, и когда я добавляю к нему значения, мне нужно добавить значения в отдельный список, так что вот мой код

 class MedPreC extends StatefulWidget {
  @override
  _MedPreCState createState() => _MedPreCState();
}
//When ini med will get values from firebase no error here
List<String> med = new List<String>();
//this is used as children of column
List<Widget> containerList = [];
//initial value of dropdown
String selectedScale = "";

class _MedPreCState extends State<MedPreC> {
//When Init get value from firestore and store it into med list  
initState() {
    Firestore.instance.collection("Med").getDocuments().then((value) {
      if (value.documents.length > 0) {
        for (var i = 0; i < value.documents.length; i  ) {
          med.add(value.documents[i].data["Name"]);
          print(med[i]);
          print(med.length);
        }
      } else {
        print("Error Med Value not found");
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(20, 70, 20, 0),
      child: Container(
        child: Column(
          children: [
            Expanded(
              child: Container(
                color: Colors.white,
                height: 400,
                width: double.infinity,
                child: SingleChildScrollView(
                  child: Column(
//containre list above made list of widgets
                    children: containerList,
                  ),
                ),
              ),
            ),
            RaisedButton(
              child: Text("Add"),
              onPressed: () {
                setState(() {
//Add values into containerList
                  containerList.insert(0, returnWidget());
                });
              },
            )

RaisedButton(
                  child: Text("Save"),
                  onPressed: () {
                   //Save the values from different container to the list  rStorage
                  },
                )
              ],
            ),
          ),
        );
      }
  

Вот где все проблемы

   Widget returnWidget() {
    if (med != null) {
      print(med.elementAt(1));
      return Padding(
        padding: const EdgeInsets.all(2.0),
        child: Container(
          height: 35,
          color: Colors.yellow,
//This Drop Down gives me error
//And i also need to add a TextField  to this container if you have time it is on an external //button() not in this  function click even shuld be able to get all values and save it into another //list
          child: DropdownButtonHideUnderline(
            child: SizedBox(
              width: double.infinity,
              child: DropdownButton(
                value: selectedScale,
                hint: Text('  Units '),
                onChanged: (value) {
                  setState(() {
                    selectedScale = value;
                  });
                },
                items: med
                    .map(
                      (e) => DropdownMenuItem(
                        child: new Text(e),
                        value: e,
                      ),
                    )
                    .toList(),
              ),
            ),
          ),
        ),
      );
    } else {
      print('Med list not loaded');
      return Text("Medisnot loaded");
    }
  }
}

class Xyz {
  Xyz(this.med, this.req);
  final String med, req;
}
//This is where all the data is stored on button click
List<Xyz> rStorage = new List<Xyz>();
  

Короче говоря, мне нужно динамически генерировать выпадающий список и текстовое поле при нажатии кнопки
И при нажатии другой кнопки мне нужно сохранить все эти данные, которые вводятся в эти Dd и текстовое поле, в список (rStorage)

Комментарии:

1. Можете ли вы переписать свой вопрос? Если вызывает головную боль.

2. я пытался упростить его. Извините, мои навыки английского и общения плохие. Я нашел ответ, хотя и разместил его здесь

Ответ №1:

Для этого. вместо использования функции для создания этих динамических виджетов используйте класс и его экземпляры. Создайте новый экземпляр и сохраните его в списке контейнеров. Теперь вы можете получить доступ к раскрывающемуся значению и значению текстового поля, перейдя в этот экземпляр

     import 'package:flutter/material.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    class MedPreC extends StatefulWidget {
      @override
      _MedPreCState createState() => _MedPreCState();
    }
    
    List<String> med = new List<String>();
    List<MyDynamicWidget> containerList = [];
    String selectedScale = "";
    List<String> myStrings = new List<String>();
    
    class _MedPreCState extends State<MedPreC> {
      initState() {
//Use your firebase or generate your own Stinglist here
        Firestore.instance.collection("Med").getDocuments().then((value) {
          if (value.documents.length > 0) {
            for (var i = 0; i < value.documents.length; i  ) {
              med.add(value.documents[i].data["Name"]);
            }
          } else {
            print("Error Med Value not found");
          }
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.fromLTRB(20, 70, 20, 0),
          child: Container(
            child: Column(
              children: [
                Expanded(
                  child: Container(
                    color: Colors.white,
                    height: 400,
                    width: double.infinity,
                    child: SingleChildScrollView(
                      child: Column(
                        children: containerList,
                      ),
                    ),
                  ),
                ),
                Row(
                  children: [
                    Spacer(),
                    RaisedButton(
                      child: Text("Add"),
                      onPressed: () {
                        setState(() {
                          containerList.insert(0, new MyDynamicWidget());
                        });
                      },
                    ),
                    Spacer(),
                    RaisedButton(
                      child: Text("Remove"),
                      onPressed: () {
                        setState(() {
                          containerList.removeAt(0);
                        });
                      },
                    ),
                    Spacer(),
                    RaisedButton(
                      child: Text("Print"),
                      onPressed: () {
                        containerList.forEach((element) {
                          print(element.myController.text.toString());
                          print(element.mySelectedScale.toString());
                        });
                      },
                    ),
                    Spacer(),
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
    
    class MyDynamicWidget extends StatefulWidget {
      final TextEditingController myController = new TextEditingController();
      String mySelectedScale = med.length > 0 ? med[0] : "Loading";
      @override
      _MyDynamicWidgetState createState() => _MyDynamicWidgetState();
    }
    
    class _MyDynamicWidgetState extends State<MyDynamicWidget> {
      @override
      Widget build(BuildContext context) {
        return Container(
          width: double.infinity,
          color: Colors.yellow,
          child: Column(
            children: [
              Container(
                height: 50,
                child: DropdownButton<String>(
                  items: med.map((String dropDownStringItem) {
                    return DropdownMenuItem<String>(
                      value: dropDownStringItem,
                      child: Text(dropDownStringItem),
                    );
                  }).toList(),
                  onChanged: (value) {
                    setState(() {
                      widget.mySelectedScale = value;
                    });
                  },
                  value: widget.mySelectedScale,
                ),
              ),
              TextField(
                controller: widget.myController,
              ),
            ],
          ),
        );
      }
    }