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