我想要實作的目標:僅當網頁以狀態 200 回應時才顯示 FAB。
以下是我的代碼的必要部分,我使用異步方法檢查網頁:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
late Future<Widget> futureWidget;
void _incrementCounter() {
setState(() {
_counter ;
});
}
@override
void initState() {
super.initState();
futureWidget = _getFAB();
}
Future<Widget> _getFAB() async {
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// return something to create FAB
return const Text('something');
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load url');
}
}
如果快照有資料,我可以使用以下 FutureBuilder 獲得結果:
body: Center(
child: FutureBuilder<Widget>(
future: futureWidget,
builder: (context, snapshot) {
if (snapshot.hasData) {
return FloatingActionButton(
backgroundColor: Colors.deepOrange[800],
child: Icon(Icons.add_shopping_cart),
onPressed:
null); // navigate to webview, will be created later
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
)
我的問題是我想在這里使用它,作為一個 floatingActionButton 小部件:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
[further coding...]
),
body: // Indexed Stack to keep data
IndexedStack(
index: _selectedIndex,
children: _pages,
),
floatingActionButton: _getFAB(),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>
[further coding...]
但在這種情況下,Flutter 拋出錯誤 引數型別“Future”不能分配給引數型別“Widget?” .
當然,因為我沒有以這種方式使用 FutureBuilder。但是當我在上面的編碼中使用 FutureBuilder 時,Flutter 會期望更多的位置引數,例如 column。這以完全不同的視圖結束,因為 FAB 不再放置在典型 FAB 位置的索引堆疊上。
我已經搜索了幾個小時來尋找類似的問題,但一無所獲。也許我的代碼太復雜了,但 Flutter 對我來說還是個新手。如果有人可以幫助我,那就太好了:)
uj5u.com熱心網友回復:
您可以使用 just _getFAB() 方法來執行此操作。您不能將 _getFab() 方法的回傳值分配給任何小部件,因為它具有回傳型別 Future。而且,當您嘗試從 FutureBuilder 回傳 FAB 時,它將在 Scaffold 主體內回傳 FAB。
因此,我建議您從 _getFAB() 方法中獲取資料并將這些資料分配給類級別變數。它可以是 bool、map 或模型類等。您必須在小部件樹中放置條件陳述句以填充資料獲取之前和資料獲取之后的狀態。然后呼叫 setState((){}) 它將使用新資料重建小部件樹。下面是一個簡單的例子。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class FabFuture extends StatefulWidget {
const FabFuture({Key? key}) : super(key: key);
@override
State<FabFuture> createState() => _FabFutureState();
}
class _FabFutureState extends State<FabFuture> {
bool isDataLoaded = false;
@override
void initState() {
super.initState();
_getFAB();
}
Future<void> _getFAB() async {
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
if (response.statusCode == 200) {
isDataLoaded = true;
setState(() {});
} else {
isDataLoaded = false;
//TODO: handle error
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: const Center(
child: Text('Implemet body here'),
),
floatingActionButton: isDataLoaded
? FloatingActionButton(
backgroundColor: Colors.deepOrange[800],
child: const Icon(Icons.add_shopping_cart),
onPressed: null)
: const SizedBox(),
);
}
}
在這里,我使用了一個簡單的布林值來確定是否應該顯示 FAB。FAB 僅在成功獲取資料后才會顯示。在實踐了這些方法并且您對它們充滿信心之后,我想建議學習狀態管理解決方案來處理這些型別的作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/477916.html
