我正在尝试更好地理解Futures in Flutter。在本例中,我的应用调用了一个API来获取Future<String>
类型的一些信息。我想在Text()
小部件中显示这些信息。但是,由于我的String
被 Package 在Future
中,我无法将这些信息放入Text()
小部件中。我不知道如何在不借助FutureBuilder
创建小部件树的情况下处理这个问题。
下面的例子使用了一个FutureBuilder
,它运行得很好。注意,我已经注解掉了下面靠近底部的一行:Future<String> category = getData();
是否可以将category
转换为String
,然后将其放到我的Text()
小部件中?
import 'package:flutter/material.dart';
import 'cocktails.dart';
class CocktailScreen extends StatefulWidget {
const CocktailScreen({super.key});
@override
State<CocktailScreen> createState() => _CocktailScreenState();
}
class _CocktailScreenState extends State<CocktailScreen> {
@override
Widget build(BuildContext context) {
Cocktails cocktails = Cocktails();
Future<String> getData() async {
var data = await cocktails.getCocktailByName('margarita');
String category = data['drinks'][0]['strCategory'];
print('Category: ${data["drinks"][0]["strCategory"]}');
return category;
}
FutureBuilder categoryText = FutureBuilder(
initialData: '',
future: getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
}
return const CircularProgressIndicator();
},
);
//Future<String> category = getData();
return Center(
child: categoryText,
);
}
}
下面是我的Cocktails
类:
import 'networking.dart';
const apiKey = '1';
const apiUrl = 'https://www.thecocktaildb.com/api/json/v1/1/search.php';
class Cocktails {
Future<dynamic> getCocktailByName(String cocktailName) async {
NetworkHelper networkHelper =
NetworkHelper('$apiUrl?s=$cocktailName&apikey=$apiKey');
dynamic cocktailData = await networkHelper.getData();
return cocktailData;
}
}
下面是我的NetworkHelper
类:
import 'package:http/http.dart' as http;
import 'dart:convert';
class NetworkHelper {
NetworkHelper(this.url);
final String url;
Future<dynamic> getData() async {
http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
var decodedData = jsonDecode(data);
return decodedData;
} else {
//print('Error: ${response.statusCode}');
throw 'Sorry, there\'s a problem with the request';
}
}
}
2条答案
按热度按时间3duebb1j1#
是的,您可以在不使用Using
FutureBuilder
的情况下,通过在initState()
中调用Future
,并使用then
关键字来实现获取Future
的值并根据更新状态,以便在Future返回快照时更新状态。在这里,我将
text
变量设置为可空,然后在Text()
小部件的实现中,我将其设置为一个loading文本作为默认值,直到Future
完成为止。ccrfmcuu2#
最好的方法是使用
FutureBuilder
:但如果您不想使用
FutureBuilder
,请首先定义一个字符串变量,如下所示,然后将adasd更改为:然后在initState中调用它:
并像这样使用它:
记住在构建方法之外而不是在构建方法内部定义
category
、getData
和cocktails
。