颤振添加到列表崩溃<Widget>类型问题



我有一个不明白的问题。

Widget build(BuildContext context) {
List<Widget> menuList = menuCategories.map((category) {
return ExpansionTile(
title: CustomExpansionTileHeader(
icon: category.icon,
label: category.label,
),
children: category.children
.map((item) => ListTile(
title: Text(item.label),
onTap: item.onTap,
))
.toList());
}).toList();
print(menuList);
menuList.insert(
0,
DrawerHeader(
child: Text(
'',
style: TextStyle(color: Colors.white, fontSize: 25),
),
decoration: BoxDecoration(
color: Colors.green,
// image: DecorationImage(
// fit: BoxFit.fill,
// image: AssetImage('assets/images/cover.jpg'))),
)));
return Drawer(
child: ListView(padding: EdgeInsets.zero, children: menuList

正如你所看到的,我正在尝试用一些ExpansionTile小部件创建列表类型的小部件,但也添加了DrawerHeader作为索引0。之后,我想像在儿童列表中的抽屉小部件一样返回列表。

当我打印menuList时(在将DrawerHeader添加到列表之前(,它会打印[ExpansionTile,ExpansionTile,ExpansionTile],当我打印Menu list.runtimeType时,我得到list type ExpansionTile。这是我不明白的部分。该列表本应是"小部件列表",但不知何故发生了更改。

当我将DrawerHeader添加到列表时,这会导致崩溃,因为它是不同的提示。

如果这很重要的话,我正在构建Flutter网络应用程序。

请帮助:(

执行List<Widget> menuList = menuCategories.map((category) {时,使用泛型字段指定类型。Dart错误地推断您希望此可迭代对象的类型为ExpansionTile

进行

List<Widget> menuList = menuCategories.map<Widget>((category) {

更明确地告诉dart你希望它是什么类型。

@Christopher Moore的答案比下面提到的方法要好。

它是映射后的tooList()调用,它总是返回List<ExpansionTile>。这更像是一种达特式的安全机制。因此,与其插入到现有列表中,不如将其收集为单独的列表,并使用排列运算符将这些元素添加到新列表中,如下所示。dartpad中提供了实时版本。

import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Drawer Demo'),
),
drawer: MyWidget(),
body: Center(
child: Text('Hello'),
),
),
);
}
}
class Item {
String label;
Function onTap;
Item({this.label, this.onTap});
}
class Category {
Icon icon;
String label;
List<Item> children;
Category({this.icon, this.label, this.children});
}
class MyWidget extends StatelessWidget {
final menuCategories = [
Category(
icon: Icon(Icons.ac_unit),
label: 'ac_unit',
children: [
Item(label: 'Voltas'),
Item(label: 'Haier'),
],
),
Category(
icon: Icon(Icons.computer),
label: 'computers',
children: [
Item(label: 'HP'),
Item(label: 'Dell'),
],
),
];
@override
Widget build(BuildContext context) {
final categoryList = menuCategories.map((Category category) {
return ExpansionTile(
title: ListTile(
title: Text(category.label),
),
children: category.children
.map((item) => ListTile(
title: Text(item.label),
onTap: item.onTap,
))
.toList());
}).toList();
List<Widget> menuList = [
DrawerHeader(
child: Text(
'Categories',
style: TextStyle(color: Colors.white, fontSize: 25),
),
decoration: BoxDecoration(
color: Colors.green,
// image: DecorationImage(
// fit: BoxFit.fill,
// image: AssetImage('assets/images/cover.jpg'))),
),
),
...categoryList
];
return Drawer(
child: ListView(padding: EdgeInsets.zero, children: menuList));
}
}

您可以在普通的dartpad中测试以下代码,以验证您所看到的相同问题。

void main() {
List<A> menus = [B('s'),B('fd')].toList();
menus.insert(0, C('1'));
print(menus);
}
class A {

}
class B extends A {
String label;
B(this.label);
}
class C extends A {
String label;
C(this.label);
}

最新更新