flutter - 提供者状态管理实施。将函数放入 create: property
问题描述
我完全迷失在状态管理领域。尝试了多个教程、文章,甚至查看了 Github 类似的项目。不知道如何在我的天气应用程序中实现提供程序。
class WeatherMainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: kBackgroundColor,
child: SafeArea(
child: ChangeNotifierProvider<WeatherModel>(
create: (context) => ApiCall().getWeather('New York'),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: EdgeInsets.only(
bottom: 30,
top: 15,
left: 30,
right: 30,
),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Today 28. apr',
style: TextStyle(
color: kAccentColor,
fontSize: 18,
fontWeight: FontWeight.w400,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MenuSearchButton(
boxSize: 60,
onPressed: () => print('search prssed'),
content: Icon(
Icons.search,
color: Colors.white,
size: 30,
),
),
MenuSearchButton(
boxSize: 60,
onPressed: () => print('menu pressed'),
content: Icon(
Icons.menu,
color: Colors.white,
size: 30,
),
),
],
),
],
),
Container(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'12',
style: TextStyle(
color: Colors.white,
fontSize: 100,
),
),
Container(
padding: EdgeInsets.only(left: 10.0),
child: Row(
children: <Widget>[
Icon(
Icons.cloud,
color: Colors.white,
size: 25.0,
),
SizedBox(width: 15.0),
Text(
'Raining',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
],
),
),
],
),
),
],
),
),
Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
bottom: 30,
top: 15,
left: 60,
right: 60,
),
child: Text(
'Put on your coat, and don\'t forget the umbrella.',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
Divider(
color: kAccentColor,
),
Container(
margin: EdgeInsets.only(
bottom: 30,
top: 15,
left: 30,
right: 30,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
DetailedCard(
header: 'HUMIDITY',
headerColor: kAccentColor,
text: '87%',
textColor: Colors.white,
),
DetailedCard(
header: 'WIND M/S',
headerColor: kAccentColor,
text: '4,1',
textColor: Colors.white,
),
DetailedCard(
header: 'FEELS LIKE',
headerColor: kAccentColor,
text: '18',
textColor: Colors.white,
),
],
),
),
],
),
],
),
),
),
);
}
}
所以我有一个模型类 WeatherModel 它基本上是空的,只包含天气信息的构造函数。ApiCall 类是所有网络发生的地方,它返回填充数据的 WeatherModel 对象。但是对于像这样的 ChangeNotifier,我会得到错误:'返回类型'Future'不是'WeatherModel',正如匿名闭包所定义的那样。'
我读到 ChangeNotifierProvider 在创建时应该只接收一个对象,而我正在向它传递一个函数。但我不知道还能在哪里调用该 getWeather 函数?完全迷失了。
编辑:
ApiCall.dart
class ApiCall extends ChangeNotifier{
Future<WeatherModel> getWeather(String cityName) async {
String url =
'https://api.openweathermap.org/data/2.5/weather?q=$cityName&appid=$apikey';
http.Response response = await http.get(url);
if (response.statusCode == 200) {
var weatherData = jsonDecode(response.body);
return WeatherModel(
temp: weatherData['main']['temp'] - 273.15,
feelsLike: weatherData['main']['temp'] - 273.15,
condition: weatherData['weather'][0]['main'],
humidity: weatherData['main']['humidity'],
windSpeed: weatherData['wind']['speed'],
);
} else {
throw Exception('Ooops something went wrong');
}
}
}
天气模型.dart
class WeatherModel{
final double temp;
final double windSpeed;
final int feelsLike;
final int humidity;
final String condition;
WeatherModel({
this.temp,
this.windSpeed,
this.feelsLike,
this.humidity,
this.condition,
});
}
解决方案
There are several change which you should make to work your code.
Change following line
child: ChangeNotifierProvider<WeatherModel>(
To
child: ChangeNotifierProvider< ApiCall >(
You have to provide class name which extends ChangeNotifier.
You have to call notifyListeners() at the end of method, on which call you want to change data.
else {
throw Exception('Ooops something went wrong');
}
notifyListeners(); // added line
}
getWeather should not return any value. Instead of that you can create any WeatherModel object in ApiCall class and update it in that method and access that object wherever you want to use that data.
Update:
child: ChangeNotifierProvider<ApiCalll>( create: (context) => ApiCall()
You can call this method in following way.
Provider.of<ApiCall>(context).getWeather('New York');
推荐阅读
- angularjs - 如何对在 AngularJS 中加载相同 URL 的链接做出反应?
- react-native - react-native bundler 可以检测到未使用的文件吗?
- mysql - 如何在查询中将两个或多个表内部连接在一起?
- angular - 如何修复 ControlValueAccessor 中的“获取价值”
- java - 在单线程环境中使用像 Hashtable 这样的线程安全集合类有什么缺点吗?
- java - 如何在android中retrofit2的响应模型类中提及“可选”和“必需”字段
- html - 如果不移动“框”,似乎无法将文本移到右侧
- hyperledger-fabric - 订购者客户端状态代码:(2) CONNECTION_FAILED。说明:拨号连接超时 [localhost:7050]
- django - 在 django_tables2 中搜索特定数据后如何修复分页
- javascript - 重新分配作为参考传递的对象不起作用