什么是最接近Dart的List.asMap().forEach()返回列表的方法?

x6yk4ghg  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(83)

在第一个屏幕(StatelessWidget)中,我们显示一个单词列表。在第二个屏幕(StatefulWidget)中,可以通过TextField编辑一个单词。

我们通过Navigator.pop返回修改后的单词,但是标记为“无效”的赋值就是这样。使用words.map创建了一个全新的列表,尽管它是一个闭包,但由于缺少words的索引,我们无法存储修改后的单词。
使用List.asMap()可以通过发送索引来解决这个问题,但是List.asMap().forEach()不会返回一个我们可以用于Column的孩子的列表。
什么是最接近Dart的List.asMap().forEach()返回列表的方法?

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: WordsWidget(
        words: ["apples", "oranges"])));
}

class EditWordWidget extends StatefulWidget {
  String word;
  EditWordWidget({super.key, required this.word});

  @override
  State<EditWordWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<EditWordWidget> {
  late TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController(text: widget.word);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Edit Word')),
      body: Column(
        children: [
          Row(children: [Text('Word: '),
              Container(
                width: 100,
                child: TextField(
                  controller: _controller,
                  onSubmitted: (String value) {
                    widget.word = value;
                  },
              )),
          ]),
          ElevatedButton(
            onPressed: () {
              Navigator.pop(context, widget.word);
            },
            child: const Text('Done'),
          )
        ]
      ),
    );
  }
}

class WordsWidget extends StatelessWidget {
  List<String> words;

  WordsWidget({Key? key, required this.words}) : super(key: key) {}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Words')),
      body: Center(
        child: Column(
          children: words.map((word) =>
            Row(
              children: [
                Text('${word}   '),
                ElevatedButton(
                  onPressed: () async {
                    final new_word = await Navigator.push(
                      context,
                      MaterialPageRoute(builder:
                        (context) => EditWordWidget(word: word)),
                    );
                    word = new_word; // ineffectual
                  },
                  child: const Text('Edit'),
                ),
              ],
            ),
          ).toList(),
        ),
      ),
    );
  }
}
7uhlpewt

7uhlpewt1#

我认为你把这件事弄得太复杂了。如果你想在List中建立一个索引,只需要用索引迭代即可。

children: [
            for (var i = 0; i < words.length; i += 1)
              Row(
                children: [
                  Text('${words[i]}   '),
                  ElevatedButton(
                    onPressed: () async {
                      // ...
                      words[i] = new_word;
                    },
                    child: const Text('Edit'),
                  ),
                ],
              ),
          ],

或者,package:collection提供了一个mapIndexed扩展方法,允许您执行以下操作:

children: words.mapIndexed((i, word) => Row(...)).toList(),

请注意,尽管上述方法会改变wordsList,但它们在Flutter应用程序中不会有任何可见的效果,因为WordsWidgetStatelessWidget。要正确重建其widget树,您还应该将其更改为StatefulWidget,并将words[i] = new_word;突变移动到setState回调中。

相关问题