![](/img/trans.png)
[英]Flutter/Firestore - type 'List<dynamic>' is not a subtype of type 'Widget'
[英]type 'List<dynamic>' is not a subtype of type 'List<Widget>'
我有一段代码是从 Firestore 示例中复制的:
Widget _buildBody(BuildContext context) {
return new StreamBuilder(
stream: _getEventStream(),
builder: (context, snapshot) {
if (!snapshot.hasData) return new Text('Loading...');
return new ListView(
children: snapshot.data.documents.map((document) {
return new ListTile(
title: new Text(document['name']),
subtitle: new Text("Class"),
);
}).toList(),
);
},
);
}
但我得到这个错误
type 'List<dynamic>' is not a subtype of type 'List<Widget>'
这里出了什么问题?
这里的问题是类型推断以意想不到的方式失败。 解决方案是为map
方法提供一个类型参数。
snapshot.data.documents.map<Widget>((document) {
return new ListTile(
title: new Text(document['name']),
subtitle: new Text("Class"),
);
}).toList()
更复杂的答案是,虽然children
项的类型是List<Widget>
,但该信息不会流回map
调用。 这可能是因为map
后跟toList
并且因为没有办法对闭包的返回进行类型注释。
您可以将动态列表转换为具有特定类型的列表:
List<'YourModel'>.from(_list.where((i) => i.flag == true));
我通过将Map
转换为Widget
解决了我的问题
children: snapshot.map<Widget>((data) =>
_buildListItem(context, data)).toList(),
我在 Firestore 中有一个字符串列表,我试图在我的应用程序中读取这些字符串。 当我尝试将其转换为字符串列表时,我遇到了同样的错误。
type 'List<dynamic>' is not a subtype of type 'List<Widget>'
这个解决方案帮助了我。 一探究竟。
var array = document['array']; // array is now List<dynamic>
List<String> strings = List<String>.from(array);
我认为您在某些小部件的子属性中使用了 _buildBody,因此孩子期望一个List Widget (Widget 数组)并且 _buildBody 返回一个'List dynamic' 。
以一种非常简单的方式,您可以使用一个变量来返回它:
// you can build your List of Widget's like you need
List<Widget> widgets = [
Text('Line 1'),
Text('Line 2'),
Text('Line 3'),
];
// you can use it like this
Column(
children: widgets
)
示例( flutter create test1 ; cd test1 ; edit lib/main.dart ; flutter run ):
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> widgets = [
Text('Line 1'),
Text('Line 2'),
Text('Line 3'),
];
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("List of Widgets Example")),
body: Column(
children: widgets
)
)
);
}
}
在小部件列表(arrayOfWidgets) 中使用小部件(oneWidget) 的另一个示例。 我展示了一个小部件(MyButton)如何个性化一个小部件并减少代码的大小:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Widget> arrayOfWidgets = [
Text('My Buttons'),
MyButton('Button 1'),
MyButton('Button 2'),
MyButton('Button 3'),
];
Widget oneWidget(List<Widget> _lw) { return Column(children: _lw); }
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Widget with a List of Widget's Example")),
body: oneWidget(arrayOfWidgets)
)
);
}
}
class MyButton extends StatelessWidget {
final String text;
MyButton(this.text);
@override
Widget build(BuildContext context) {
return FlatButton(
color: Colors.red,
child: Text(text),
onPressed: (){print("Pressed button '$text'.");},
);
}
}
我做了一个完整的例子,我使用动态小部件在屏幕上显示和隐藏小部件,你也可以在dart fiddle上看到它在线运行。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List item = [
{"title": "Button One", "color": 50},
{"title": "Button Two", "color": 100},
{"title": "Button Three", "color": 200},
{"title": "No show", "color": 0, "hide": '1'},
];
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Dynamic Widget - List<Widget>"),backgroundColor: Colors.blue),
body: Column(
children: <Widget>[
Center(child: buttonBar()),
Text('Click the buttons to hide it'),
]
)
)
);
}
Widget buttonBar() {
return Column(
children: item.where((e) => e['hide'] != '1').map<Widget>((document) {
return new FlatButton(
child: new Text(document['title']),
color: Color.fromARGB(document['color'], 0, 100, 0),
onPressed: () {
setState(() {
print("click on ${document['title']} lets hide it");
final tile = item.firstWhere((e) => e['title'] == document['title']);
tile['hide'] = '1';
});
},
);
}
).toList());
}
}
也许它可以帮助某人。 如果它对您有用,请让我知道单击向上箭头。 谢谢。
这对我List<'YourModel'>.from(_list.where((i) => i.flag == true));
我认为,将 List 的类型从动态更改为 String 并进行热重载后会出现此错误,热重启是解决方案..
请记住:热重启只重建 build() 函数,而不是整个类&在类顶部声明 List 不在 build() 函数之外
通过添加.toList()
更改为列表解决了问题
例子:
List<dynamic> listOne = ['111','222']
List<String> ListTwo = listOne.cast<String>();
要将每个项目转换为小部件,请使用ListView.builder()
构造函数。
通常,提供一个构建器函数来检查您正在处理的项目类型,并为该类型的项目返回适当的 Widget。
ListView.builder(
// Let the ListView know how many items it needs to build.
itemCount: items.length,
// Provide a builder function. This is where the magic happens.
// Convert each item into a widget based on the type of item it is.
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
title: item.buildTitle(context),
subtitle: item.buildSubtitle(context),
);
},
);
有一条关于用“List myList = [1,2,3]”而不是“List myList = [1,2,3]”声明您的列表的评论
声明到“列表”<“小部件”>“myList [1,2,3]”
可以确认这解决了“List”类型的错误不是“List”类型的子类型
我的解决方案是,您可以将List<dynamic>
转换为List<Widget>
,您可以在snapshot.data.documents.map
之后添加一个简单代码到snapshot.data.documents.map<Widget>
,就像我将向您展示的代码一样以下
由此
return new ListView(
children: snapshot.data.documents.map((document) {
return new ListTile(
title: new Text(document['name']),
subtitle: new Text("Class"),
);
}).toList(),
);
进入这个
return new ListView(
children: snapshot.data.documents.map<Widget>((document) {
return new ListTile(
title: new Text(document['name']),
subtitle: new Text("Class"),
);
}).toList(),
);
改变
List list = [];
对此:
List<Widget> list = [];
解决了我的问题!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.