[英]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.