前言
这是一个使用flutter写的天气预报APP,主要使用了以下几个插件,入门级练练手。
dio
:网络请求插件,用于获取天气信息
fluttertoast
:弹出toast提示信息
shared_preferences
:简单的数据存储,用于保存设置过的天气预报信息
intl
:日期格式化
fluttertoast
:提示信息
mobx
:状态管理
flutter_mobx
:状态管理
easy_localization
:国际化
mobx_codegen
:状态管理自动生成代码的依赖
build_runner
:自动生成代码依赖
项目GitHub地址:d9l_weather
界面
首先搜集一些天气预报APP的设计稿,确定一下自己的界面。看到有很多好看的,但是并不想做的太复杂。为了省事就找了一个模仿一下,下面是实现的效果图:
然后分析一下这个页面,大主体就是一个列布局(Column),中间穿插行布局(Row)。详细的布局这里就不写,可以在这查看源码home_page.dart
界面堆好之后,再做一个搜索城市的页面,一个搜索框加列表就可以了,怎么简单怎么来。页面通过右上角的设置按钮进入。
API接口调用
页面都写好之后就需要把数据替换成真实数据了,这里使用了和风天气的API获取天气数据,注册之后就能使用。但是普通用户有些接口是不能用的,但是对这个APP来说,能够查到天气信息、最近三天和生活指数这些信息就足够了。
要请求接口,这里使用dio
插件来实现。使用单例模式即可。
新建一个http.dart
文件,简单写一下get和post方法,如下。
import 'package:dio/dio.dart';
class Http {
static Dio dio;
factory Http() => _getInstance();
static Http get instance => _getInstance();
static Http _instance; // 单例对象
static Http _getInstance() {
if (_instance == null) {
_instance = Http._internal();
}
return _instance;
}
Http._internal() {
dio = Dio(BaseOptions(connectTimeout: 60000, receiveTimeout: 15000, sendTimeout: 15000));
dio.options.baseUrl = rootUrl;
}
static final String rootUrl = 'https://free-api.heweather.net/s6';
static final String key = 'd77fe2f561f44c1b8a8d365ad503e9bf';
Future get(String path, Map params) async {
try {
Response response = await dio.get(path, queryParameters: params);
return response.data;
} catch (e) {
print(e);
return null;
}
}
Future post(String path, Map data) async {
try {
Response response = await dio.post(path, data: data);
return response.data;
} catch (e) {
return null;
}
}
}
使用方法,传入请求地址和参数即可
Http().get('/weather/now', {
'location': cid,
'lang': D9l().lang,
'key': Http.key,
});
如获取实时天气的方法如下:
// 实况天气
Future _getNow() async {
var result = await Http().get('/weather/now', {
'location': cid,
'lang': D9l().lang,
'key': Http.key,
});
if (result != null) {
status = result['HeWeather6'].first['status'];
if (status == 'ok') {
basic = Basic.fromJson(result['HeWeather6'].first['basic']);
update = Update.fromJson(result['HeWeather6'].first['update']);
now = Now.fromJson(result['HeWeather6'].first['now']);
}
}
}
shared_preferences
在搜索完一个城市的天气后,需要把这个城市的id
保存在shared_preferences
中,这样关闭app下次再打开的时候才能显示上一次查询的城市天气,或者需要保存多个城市天气预报的时候,也可以保存。
保存只需要一行代码:
SpClient.sp.setString('cid', cid);
shared_preferences
的使用也是使用了单例模式,和http.dart
一样
国际化
本项目使用了easy_localization
插件来实现,个人觉得这还是一个比较简单好上手的一个插件
runApp(EasyLocalization(child: MyApp()));
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var data = EasyLocalizationProvider.of(context).data;
return EasyLocalizationProvider(
data: data,
child: MaterialApp(
title: 'd9l weather',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
EasylocaLizationDelegate(
locale: data.locale,
path: 'assets/langs', // 多语言路径
),
],
supportedLocales: [Locale('en', 'US'), Locale('zh', 'CN')],
locale: data.savedLocale,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
),
);
}
}
然后编写自己的国际json文件,放在assets/langs
路径下,并且在pubspec.yaml
中进行声明,并在Text
组件中这样使用AppLocalizations.of(context).tr('wind')
,wind是你在json中使用的key,它会根据当前的语言显示。
切换语言也很简单
var data = EasyLocalizationProvider.of(context).data;
data.changeLocale(Locale("zh", "CN"));
最后
这个项目很简单,也只是用了很少的东西,主要是练练手吧。也没太多东西能够介绍的。后面有时间的话会继续完善。感兴趣的可以关注一下。GitHub给star支持,谢谢!
最后再放一下本项目的GitHub地址 d9l_weather
更新
文章于2020.3.23日晚更新,对界面进行了重新排版,项目整体都做了较大改变,并且新增了国际化、状态管理。继续完善中~