我目前正在為大學開發一款小型答題器游戲,這是我第一次使用 flutter dart。
我創建了一個顯示不同升級的升級選項卡。正在從 .json 檔案存盤和加載這些升級
每當我嘗試打開升級選項卡時,dart 都會拋出例外 -> RangeError (index): Index out of range: no indices are valid: 0 這是由于 json 尚未加載且 axeList 為空但由于 dart 呼叫多次構建方法之后被加載
仍然......有一個錯誤的框架。這是一個放慢速度的 gif:
放慢 gif (imgur.com)
這是我的代碼:
class Upgrades extends StatefulWidget {
const Upgrades({Key? key}) : super(key: key);
@override
State<Upgrades> createState() => _UpgradesState();
}
class _UpgradesState extends State<Upgrades> with Store {
List axeList = [];
@override
void initState() {
readJson();
super.initState();
}
Future<void> readJson() async {
final String response = await rootBundle.loadString("/axe_list.json");
final data = await json.decode(response);
setState(() {
axeList = data["axe"];
});
}
@override
Widget build(BuildContext context) {
return //I need the content of axeList in this buildMethod
命令:
- 初始化狀態()
- 讀取Json()
- build() |-> 例外,因為 axeList 尚未加載
- readJson 就緒
問題是我不能在 initState 中使用異步:
@override
Future<void> initState() async{
// Call the readJson method when the app starts & ensure loaded
await readJson();
super.initState();
}
這將在以下例外中解決:“_UpgradeState.initState() 回傳了 Future。State.initState() 必須是沒有異步關鍵字的無效方法”
在應用程式啟動時加載 json 似乎也不是解決方案,因為升級不會在啟動時直接呼叫,而是在稍后呼叫。另外 id 必須在 7 個建構式中交出資料
我如何確保在構建方法之前加載異步方法?謝謝答案<3
uj5u.com熱心網友回復:
aFutureBuilder將解決您的問題,請按照此操作。
首先,用這個替換你的方法:
由于我們將使用FutureBuilder,因此無需SetState(() {}):
Future<List> readJson() async {
final String response = await rootBundle.loadString("/axe_list.json");
final data = await json.decode(response);
return data["axe"];
}
然后在build():
return FutureBuilder<List>(
future: readJson(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
List axeList = snapshot.data!;
return YourMainWidget(); // here use axeList to generate the widgets
}
return const Text("no data");
},
);
替換YourMainWidget()為您需要的主要小部件axeList。
uj5u.com熱心網友回復:
您可以使用FutureBuilder小部件在 UI 中異步加載資料。
下面的例子展示了如何使用它。
FutureBuilder<List<dynamic>>(
future: readJson(),
builder: (context,snapShot){
switch(snapShot.connectionState){
case ConnectionState.none:
// show error widget
break;
case ConnectionState.waiting:
// show loading widget
break;
case ConnectionState.active:
// show loading widget
break;
case ConnectionState.done:
// show widget that consumes data
//final data = snapShot.data
break;
}
//error widget if future fails or not handled
return const Text("Error");
},
),
- 您不需要再次呼叫setState()來構建小部件
- 確保readJson()的回傳型別與傳遞給 FutureBuilder< List >() 的回傳型別相同。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/533680.html
標籤:扑镖异步异步等待小部件
