如何循环和呈现预定义小部件列表?

How do I loop and render through a list of predefined widgets?

所以我在下面定义了一个预定义选项列表

final List<DropdownMenuItem> grades = <DropdownMenuItem>[
    DropdownMenuItem(value: "Highschool", child: Text('Highschool')),
    DropdownMenuItem(value: "Senior High", child: Text('Senior High')),
    DropdownMenuItem(value: "College", child: Text('College'))];

而我想做的是遍历列表并将其放在下拉菜单下

 Form(
          child: DropdownButtonHideUnderline(
              child: ButtonTheme(
            alignedDropdown: true,
            child: DropdownButton<String>(
              value: defState,
              onChanged: (String? newValue) {
                setState(() {
                  defState = newValue!;
                });
              },
              items: grades.map((items) => return items),
              hint: Text("Grade"),
            ),
          )),
        )

但它给了我这两个错误

The argument type 'Iterable<DropdownMenuItem<dynamic>>' can't be assigned to the parameter type 'List<DropdownMenuItem<String>>?'.

Unexpected text 'return'.
Try removing the text.

有没有办法迭代列表以便我可以立即 return?

grades 列表的类型更改为 List<DropdownMenuItem<String>>:

  final List<DropdownMenuItem<String>> grades = [
    DropdownMenuItem(value: "Highschool", child: Text('Highschool')),
    DropdownMenuItem(value: "Senior High", child: Text('Senior High')),
    DropdownMenuItem(value: "College", child: Text('College'))
  ];

并且只需使用 grades 而不是地图:

DropdownButton<String>(
  value: defState,
  onChanged: (String? newValue) {
    setState(() {
      defState = newValue!;
    });
  },
  items: grades,
  hint: Text("Grade"),
),

几件事:

首先,箭头函数不需要 return 关键字。例如,下面两个函数是等价的:

grades.map((_) => 'hello')

grades.map((_) {
  return 'hello';
})

其次,错误消息说:“你给了我一个 Iterable<DropdownMenuItem<dynamic>>,但我需要一个 List<DropdownMenuItem<String>>”。

您正在创建一个 DropdownButton<String>,它将 List<DropdownMenuItem<String>> 作为其 items 参数,但您传入 grades.map( ... ).

map()Iterable 中定义,并具有以下签名:

Iterable<T> map<T>(T f(E e))

这有点不透明,但至关重要的是,它 return 是一个 Iterable<T>,其中 T 是您传入的函数的 return 类型,例如:

List<int> ints = [1, 2, 3];
Iterable<String> strings = ints.map((i) => i.toString());

要解决您的问题,您应该执行以下操作:

  1. 不要让 final 字段里面有小部件,而是让它成为一个函数。您应该避免像这样缓存小部件(除非它们是 const),因为它会干扰热重载。重要的是,该函数还应该指定 DropdownMenuItem 它的类型 returns:
List<DropdownMenuItem<String>> get grades => [
  DropdownMenuItem<String>(...),
  ...
]
  1. 您的映射函数无效,但如果您删除 return 关键字,它将是 (items) => items,这是恒等函数(即它什么都不做)。您可以删除它,它会起作用。 或者,如果您想调用某个函数,则需要对结果调用 toList(),因为 items 需要一个列表:
  items: grades,
   
  // or

  items: grades.map((grade) => ...).toList(),