我的問題是 Futures,因為它們應該在 build() 方法執行之前獲得,正如檔案所述:
必須提前獲取future,因為如果future與FutureBuilder同時創建,那么每次FutureBuilder的parent重建時,異步任務都會重新啟動。
我知道在執行構建方法之前應該在 initstate() 函式中呼叫 Futures,但我的情況不同。
我想從 api 作為 Future 獲取資料,但是我發送到 api 的請求需要用戶應該在螢屏的 build() 方法中選擇的一些引數。
而且我不知道請求的引數是什么,直到用戶在 build() 方法中選擇,我必須在 build() 方法中呼叫 api 并在那里使用 FutureBuilder,但這使得 FutureBuilder 不斷被呼叫,我不想那樣。
基本上,我不想無限期地呼叫 FutureBuilder,而且我不能將 Future 放在 initState() 中,因為 Future 需要用戶稍后在 build() 方法中顯示螢屏時選擇的一些引數。
在構建方法中:
FutureBuilder<List<LatLng>>(
builder: (context, snapshot) {
if (snapshot.hasData) {
return PolylineLayer(
polylines: [
Polyline(
points: snapshot.data!,
strokeWidth: 4,
color: Colors.purple),
],
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return Container();
}
},
future: Provider.of<NavigationProvider>(context)
.getNavigationPoints(pointToGoTo!),
),
現在,如果您查看代碼,在最后幾行,我將引數 pointToGoTo 發送到呼叫后端的函式。
簡單地說,我想擺脫呼叫 api 并將資料作為未來內部構建方法取回,我想在 initState 或其他地方執行它,以防止構建方法無限期地呼叫后端。
有沒有辦法解決這個問題?提前致謝。
uj5u.com熱心網友回復:
首先,創建未來狀態變數和一個可為空的引數,并在使用 FutureBuilder 時將其與條件 if 一起使用。
我會建議檢查修復常見的 FutureBuilder 和 StreamBuilder 問題
現在您可以按照此示例進行操作。API 召回時缺少 progressBar,在這種情況下 StreamBuilder 可能是更好的選擇。
class Foo extends StatefulWidget {
const Foo({super.key});
@override
State<Foo> createState() => _FooState();
}
class _FooState extends State<Foo> {
int? params;
Future<int> fetch(int? data) async {
await Future.delayed(Duration(seconds: 1));
return (params ?? 0) * 2;
}
late Future<int> future = fetch(params);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
DropdownButton<int?>(
value: params,
items: List.generate(
12,
(index) => DropdownMenuItem(
value: index,
child: Text("$index"),
)).toList(),
onChanged: (value) {
future =
fetch(params); // this will only call api with update data
setState(() {
params = value;
});
},
),
if (params != null)
FutureBuilder<int>(
future: future,
builder: (context, snapshot) {
if (snapshot.hasData) return Text("${snapshot.data}");
return CircularProgressIndicator();
},
)
],
),
);
}
}
uj5u.com熱心網友回復:
class Testing extends StatefulWidget {
const Testing({super.key});
@override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
bool isFetched = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Consumer<SomethingProvider>(
builder: (context, prov, child) {
if (!isFetched) {
prov.getData("a", "b");
Future.delayed(const Duration(milliseconds: 200), () {
isFetched = true;
});
}
if (prov.newData.isNotEmpty) {
return Column(
// make widget tree from here
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class SomethingProvider extends ChangeNotifier {
List newData = [];
Future getData(param1, param2) async {
newData = ["testingdata"];
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/533241.html
標籤:安卓IOS扑异步未来
