在我的第一个 Flutter 应用程序中单击一个按钮后,我想针对 OpenWeatherMap-API 执行网络请求(Rest API)。基本上我正在关注本教程:Fetch data from the internet
因此,我创建了 API 调用,它遵循教程并且工作起来非常棒:
class OpenWeatherApi {
static const _API_KEY = "asdbaklsadfkasdlfkasdjfl";
Future<CurrentWeather> getCurrentWeather(String location) async {
final url =
"https://api.openweathermap.org/data/2.5/weather?q=$location&APPID=$_API_KEY";
final response = await get(url);
final responseJson = json.decode(response.body);
return new CurrentWeather.fromJson(responseJson);
}
}
我在有状态小部件中调用 API:
class _MyHomePageState extends State<MyHomePage> {
String _currentWeather = "";
void _callWeatherApi() {
var api = new OpenWeatherApi();
api.getCurrentWeather("Waldershof, Germany").then((weather) {
setState(() {
_currentWeather = weather.getTextualRepresentation();
});
}, onError: (error) {
setState(() {
_currentWeather = error.toString();
});
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
border: InputBorder.none, hintText: 'Please enter a Location'),
),
new RaisedButton(
onPressed: () {
_callWeatherApi();
},
child: new Text("Get Weather"),
),
new Text(
'$_currentWeather',
style: Theme.of(context).textTheme.display1,
),
],
),
);
}
}
点击RaisedButton
,我调用我的函数_callWeatherApi
。此函数执行网络请求并在之后更新我的小部件。基本上它工作得很好。
但在示例中,他们使用 FutureBuilder
-Widget 进行网络请求,这在状态处理方面具有一些不错的优势(例如显示进度指示器):
new FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return new Text(snapshot.data.title);
} else if (snapshot.hasError) {
return new Text("${snapshot.error}");
}
// By default, show a loading spinner
return new CircularProgressIndicator();
},
);
不幸的是,我不知道这个 FutureBuilder
小部件是否可以用于由按下按钮触发的网络请求。
因此,我不知道我基于按钮按下的网络请求实现是否是最先进的,或者是否可以通过使用例如改进。 FutureBuilder
还是 Flutter 中的其他小部件?
您对改进我的代码有什么建议吗?
最佳答案
您不需要编写 FutureBuilder。没有它你也可以实现。
这是另一种方法。
Write a function to return a Progressbar or Text in the _MyHomePageState class.
Widget getProperWidget(){
if(apiCall)
return new CircularProgressIndicator();
else
return new Text(
'$_currentWeather',
style: Theme.of(context).textTheme.display1,
);
}
创建一个局部变量来管理 API 调用的状态。
String _currentWeather = "";
bool apiCall = false; // New variable
将构建方法中的 Text 小部件替换为该函数并设置状态 apiCall = true。
....
new RaisedButton(
onPressed: () {
setState((){
apiCall=true; // Set state like this
});
_callWeatherApi();
},
child: new Text("Get Weather"),
),
getProperWidget()
收到请求的响应后隐藏进度条并像这样更新您的 _callWeatherApi 函数:
void _callWeatherApi() {
var api = new OpenWeatherApi();
api.getCurrentWeather("Waldershof, Germany").then((weather) {
setState(() {
apiCall= false; //Disable Progressbar
_currentWeather = weather.toString();
});
}, onError: (error) {
setState(() {
apiCall=false; //Disable Progressbar
_currentWeather = error.toString();
});
});
}
https://stackoverflow.com/questions/50014848/
相关文章:
flutter - 在 SafeArea 中获取小部件高度的正确方法
ios - 无法使用 PathProvider 依赖项构建 flutter 项目
flutter - 如何从字节数据中读取蓝牙特征并将其转换为适当的值(用于 flutter 的蓝牙)
android - 如何模拟/ stub Flutter 平台 channel /插件?
dart - Flutter - 使用 Flutter 创建自定义控件
firebase - 我应该将图片上传到 Cloud Firestore 还是 Firebase S
dart - Flutter - float 操作按钮 - 隐藏项目的可见性