本文介绍Flutter_Weather天气模块实现。效果图如下:
在这里插入图片描述
项目地址:https://github.com/Zhengyi66/Flutter_weather
首页最外层布局实现
首页包含一个顶部的城市名称展示栏和一个pageview。因此可以使用一个Column竖直的列进行包裹。
return Container(
child: Column(
children: [
//头
buildBar(context),
//pageview
Expanded(child: _buildPageView(),
)
],
),
);
使用Expanded填充剩余空间,类似Android权重属性。
PageView实现
pageview
_buildPageView()根据 loadState加载状态不同返回3个widget。加载数据时返回一个自定义的ProgressView,加载失败时返回一个失败的Widget,只有当数据加载成功时,才返回PageView。
PageView属性:
scrollDirection :滚动方向。 Axis.horizontal 横向 vertical竖向
controller : PageController 控制pageview滚动
pageSnapping : 默认为true。设置false后失去pageview的特性
顶部标题栏实现
在这里插入图片描述
如上图,横向排列的3个widget,可以使用Row进行包裹。使用GestureDetector为其增加点击事件。代码如下:
在这里插入图片描述
选择城市之后我们需要知道选择了什么城市,所以我们需要接受路由的回调Future,并添加它的回调方法,在回调方法中获得返回的城市然后重新加载数据。类似Android activityresult
数据加载
1、加载assets中json数据
因为数据调用的次数是有限制的,所以在调试的时候只能加载本地的数据了╮(╯▽╰)╭
//从assets中加载天气信息
loadWeatherAssets() async {
Future future = DefaultAssetBundle.of(context).loadString("assets/json/weather.json");
future.then((value){
setState(() {
weatherJson = value;
});
});
}
flutter推荐我们使用DefaultAssetBundle进行本地数据加载。
加载网络数据
loadWeatherData() async {
final response = await http.get(Api.WEATHER_QUERY + city);
setState(() {
weatherJson = response.body;
});
}
你没看错,就一行代码就搞定了数据加载。当然要使用await来等待加载完成,因为有等待,所以加载的方法要async在异步中进行。
Json解析
加载完数据以后进行json解析
导包
import 'dart:convert';
if(weatherJson.isNotEmpty){
WeatherBean weatherBean = WeatherBean.fromJson(json.decode(weatherJson));
if(weatherBean.succeed()){
loadState = 1;
weatherResult = weatherBean.result;
}else{
loadState = 0;
}
}
json.decode()返回的是一个dynamic任意类型。因此需要我们在手动解析。
解析对象
WeatherBean中实现如下:
在这里插入图片描述
我们需要手动写一个工厂方法WeatherBean.fromJson(Map json)手动解析。
如果解析的key是一个对象,例如上面的WeatherResult对象。则需要调用WeatherResult对象的fromJson。
为了保险起见,解析WeatherResult对象的时候加一个非空判断。
解析数组
我们再来看一下WeatherResult中又是啥。(有点多,截屏截不全了╮(╯▽╰)╭,就拷贝吧)
class WeatherResult{
final String city; //城市
final String citycode; //城市code (int)
...(省略一些)
final Aqi aqi;
final List indexs; //生活指数
final List dailys; //一周天气
final List hours; //24小时天气
WeatherResult({this.city,this.citycode,this.date,this.weather,this.temp,this.temphigh,this.templow,this.img,this.humidity,
this.pressure,this.windspeed,this.winddirect,this.windpower,this.updatetime,this.week,this.aqi,this.indexs,this.dailys,this.hours});