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