Flutter:如何从 ListView 的元素中保存数据?
Flutter: How to save data from elements of ListView?
我有一个 ListView.builder,其中包含许多 CustomCards:
ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return CustomCard(
data: list[index],
}
),
CustomCard 小部件包含一个可以编辑的 TextField。当用户更改了 CustomCard 小部件的数据时,应通过按下按钮来保存数据。我插入了一个屏幕截图以便于理解:
我现在的问题是如何从 ListView/CustomCards 访问数据。 Here Rémi Rousselet wrote that "in Flutter data can only be passed downward". Therfore I can not add the wanted data to a constructor or use a BuildContext. answer from Günter Zöchbauer says that it is expensive to use GlobalKeys for ListViews. Another idea would be to merge the two widgets into one and use a TextEditingController like suggested here 若昂·苏亚雷斯。我认为在我的情况下这会导致我试图避免的非常混乱的代码。
如何实现同时保存ListView所有CustomCards的数据?最简单、最便宜和最干净的方法是什么?有没有我不知道或者理解不正确的概念?
我认为您希望在 ListView 小部件的每一行都有两个输入,希望下面的示例对您有所帮助。
解决方法^^
create a class in which you declare a list of TextEditingController
class _HomePageState extends State<HomePage> {
List<CustomCardController> _customCardControllers = [];
List<CustomCard> _customCards = []
..add(CustomCard("US","UK"))
..add(CustomCard("TUNSIA","JAPON"))
..add(CustomCard("JAPON","CANADA"))
;
@override
void initState() {
super.initState();
_customCardControllers = List.generate(_customCards.length,
(index) => CustomCardControllers(_customCards[index]));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
body: Center(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: _customCardControllers.length,
itemBuilder: (context, index) {
return
_creatCustomCard(_customCardControllers[index].customCard,index);
}
),
ElevatedButton(onPressed: getAllValues, child:
Text("SAVE"))
],
),
),
);
}
Widget _creatCustomCard(CustomCard customCard,int index) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
key: UniqueKey(),
children: [
Row(
children: [
Expanded(child: Text("${customCard.arrival}"),flex: 1),
Expanded(child: Text("
${customCard.departure}"),flex: 1),
],
),
Row(
children: [
Expanded(
flex:1,
child: TextField(
controller:
_customCardControllers[index].textEditingControllers![0],
),
),
Expanded(
flex:1,
child: TextField(
controller:
_customCardControllers[index].textEditingControllers![1],
),
),
],
),
SizedBox(height: 15,)
],
);
}
void getAllValues() {
for(int i=0;i<_customCards.length;i++){
String value1
=_customCardControllers[i].textEditingControllers![0].text;
String value2
=_customCardControllers[i].textEditingControllers![1].text;
print("$i : arrival ${_customCards[i].arrival} : $value1 |
departure ${_customCards[i].departure} : $value2");
}
}
}
class CustomCardController{
final CustomCard customCard;
List<TextEditingController> ? textEditingControllers;
CustomCardController(this.customCard){
textEditingControllers = []
..add(new TextEditingController())
..add(new TextEditingController());
}
}
class CustomCard{
final String arrival;
final String departure;
CustomCard(this.arrival, this.departure);
}
[![在此处输入图片描述][1]]
[1]: https://i.stack.imgur.com/b0NTr.png
我有一个 ListView.builder,其中包含许多 CustomCards:
ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return CustomCard(
data: list[index],
}
),
CustomCard 小部件包含一个可以编辑的 TextField。当用户更改了 CustomCard 小部件的数据时,应通过按下按钮来保存数据。我插入了一个屏幕截图以便于理解:
我现在的问题是如何从 ListView/CustomCards 访问数据。 Here Rémi Rousselet wrote that "in Flutter data can only be passed downward". Therfore I can not add the wanted data to a constructor or use a BuildContext.
如何实现同时保存ListView所有CustomCards的数据?最简单、最便宜和最干净的方法是什么?有没有我不知道或者理解不正确的概念?
我认为您希望在 ListView 小部件的每一行都有两个输入,希望下面的示例对您有所帮助。
解决方法^^
create a class in which you declare a list of TextEditingController
class _HomePageState extends State<HomePage> {
List<CustomCardController> _customCardControllers = [];
List<CustomCard> _customCards = []
..add(CustomCard("US","UK"))
..add(CustomCard("TUNSIA","JAPON"))
..add(CustomCard("JAPON","CANADA"))
;
@override
void initState() {
super.initState();
_customCardControllers = List.generate(_customCards.length,
(index) => CustomCardControllers(_customCards[index]));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("test"),
),
body: Center(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: _customCardControllers.length,
itemBuilder: (context, index) {
return
_creatCustomCard(_customCardControllers[index].customCard,index);
}
),
ElevatedButton(onPressed: getAllValues, child:
Text("SAVE"))
],
),
),
);
}
Widget _creatCustomCard(CustomCard customCard,int index) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
key: UniqueKey(),
children: [
Row(
children: [
Expanded(child: Text("${customCard.arrival}"),flex: 1),
Expanded(child: Text("
${customCard.departure}"),flex: 1),
],
),
Row(
children: [
Expanded(
flex:1,
child: TextField(
controller:
_customCardControllers[index].textEditingControllers![0],
),
),
Expanded(
flex:1,
child: TextField(
controller:
_customCardControllers[index].textEditingControllers![1],
),
),
],
),
SizedBox(height: 15,)
],
);
}
void getAllValues() {
for(int i=0;i<_customCards.length;i++){
String value1
=_customCardControllers[i].textEditingControllers![0].text;
String value2
=_customCardControllers[i].textEditingControllers![1].text;
print("$i : arrival ${_customCards[i].arrival} : $value1 |
departure ${_customCards[i].departure} : $value2");
}
}
}
class CustomCardController{
final CustomCard customCard;
List<TextEditingController> ? textEditingControllers;
CustomCardController(this.customCard){
textEditingControllers = []
..add(new TextEditingController())
..add(new TextEditingController());
}
}
class CustomCard{
final String arrival;
final String departure;
CustomCard(this.arrival, this.departure);
}
[![在此处输入图片描述][1]] [1]: https://i.stack.imgur.com/b0NTr.png