0x00 前言

前面四篇文章:

  1. Flutter实战1 --- 写一个天气查询的APP
  2. Flutter实战2 --- 写一个天气查询的APP
  3. FFlutter实战3 --- PC上运行Flutter APP
  4. Flutter实战4 -- 天气查询APP重构之状态管理(InheritedWidget)

在第4篇文章中,为了方便管理状态,我们介绍了InheritedWidget,今天介绍ScopedModel,这是一个封装的InheritedWidget的库,使用起来更方便。

0x01 代码

本篇文章所涉及的代码:

github.com/google/flut…

分支:scoped_model

0x02 ScopedModel

ScopedModel:github.com/brianegan/s…

可以方便的将model从父Widget传递到它的后代。而且还会在model更新时重建使用该model的所有子项。该库是从Fuchsia代码库中提取的。

0x03 ScopedModel引入

pubspec.yaml里加入:

scoped_model: ^1.0.1
复制代码

然后运行flutter packages get

0x04 ScopedModel使用

ScopedModel使用,主要是下面三个类:

  1. Model

    你要继承Model这个类,实现自己的Models,这个Module类里,持有相关的数据,及实现一些业务逻辑,可以监听Model里的数据变化

  2. ScopedModel

    ScopedModel是一个Widget,确定Model的使用范围:像使用InheritedWidget一样,你需要用ScopedModel包其他Widget,而且Model也是包在ScopedModel里的,这样Model就可以沿着Widget树向下传递。

  3. ScopedModelDescendant ScopedModelDescendant也是一个Widget,在子Widget获取Model使用:使用ScopedModelDescendant,是为了在子Widget里找到相应的Model。只要是Model发生更改,它就会自动重建。

0x05 重构 -- 实现Model

新增了两个Model,分别是:

  1. CityModel

作用:获取城市列表

import 'dart:convert';import 'package:flutter/widgets.dart';
import 'package:gdg_weather/page/city/CityData.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:http/http.dart' as http;class CityModel extends Model{List<CityData> cityList = new List<CityData>();CityModel(){}static CityModel of(BuildContext context) => ScopedModel.of<CityModel>(context,rebuildOnChange: true);//获取城市列表的方法void getCityList() async {final response = await http.get('https://search.heweather.net/top?group=cn&key=ebb698e9bb6844199e6fd23cbb9a77c5');List<CityData> list = new List<CityData>();if(response.statusCode == 200){//解析数据Map<String,dynamic> result = json.decode(response.body);for(dynamic data in result['HeWeather6'][0]['basic']){CityData cityData = CityData(data['location']);list.add(cityData);}}        cityList = list;   //这里一定要,数据变化,通知widget刷新notifyListeners();}
}
复制代码
  1. WeatherModel
import 'dart:convert';import 'package:gdg_weather/page/weather/WeatherData.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:http/http.dart' as http;class WeatherModel extends Model{WeatherData weather = WeatherData.empty();void fetchWeather(String cityName) async{final response = await http.get('https://free-api.heweather.com/s6/weather/now?location='+cityName+'&key=ebb698e9bb6844199e6fd23cbb9a77c5');if(response.statusCode == 200){weather = WeatherData.fromJson(json.decode(response.body));}else{weather = WeatherData.empty();}notifyListeners();}
}
复制代码

0x06 重构 -- 原有widget重构

Model实现完后,接下来就是对原有widget重构,

第一个步是添加ScopedModel,确定Model的使用范围:

ScopedModel<CityModel>(model: CityModel(),child: ...);
复制代码

第二步是使用ScopedModelDescendant,在子Widget获取Model使用,所以重构如下:

ScopedModelDescendant<CityModel>(builder: (context,child,model){//使用modelmodel....})
复制代码
  1. CityWidget
class CityState extends State<CityWidget>{CityState(){}@overrideWidget build(BuildContext context) {// TODO: implement buildreturn ScopedModel<CityModel>(model: CityModel(),child: ScopedModelDescendant<CityModel>(builder: (context,child,model){model.getCityList();return ListView.builder(itemCount: model.cityList.length,itemBuilder: (context,index){return ListTile(title: GestureDetector(child:  Text(model.cityList[index].cityName),onTap:(){Navigator.push(context,MaterialPageRoute(builder: (context) => WeatherWidget(model.cityList[index].cityName)));},),);});},));}}
复制代码
  1. WeatherWidget
class WeatherState extends State<WeatherWidget>{String cityName;WeatherState(String cityName){this.cityName = cityName;}@overrideWidget build(BuildContext context) {// TODO: implement buildreturn Scaffold(body: Stack(fit: StackFit.expand,children: <Widget>[Image.asset("images/weather_bg.jpg",fit: BoxFit.fitHeight,),Column(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[Container(width: double.infinity,margin: EdgeInsets.only(top: 40.0),child: new Text(this.cityName,textAlign: TextAlign.center,style: new TextStyle(color: Colors.white,fontSize: 30.0,),),),Container(width: double.infinity,margin: EdgeInsets.only(top: 100.0),child: ScopedModel<WeatherModel>(model: WeatherModel(),child: ScopedModelDescendant<WeatherModel>(builder: (context,child,model){model.fetchWeather(this.cityName);return Column(children: <Widget>[Text(model.weather?.tmp,style: new TextStyle(color: Colors.white,fontSize: 80.0)),Text(model.weather?.cond,style: new TextStyle(color: Colors.white,fontSize: 45.0)),Text(model.weather?.hum,style: new TextStyle(color: Colors.white,fontSize: 30.0),)],);},),))],)],),);}}
复制代码

在使用ScopedModelScopedModelDescendant都使用到了泛型

Flutter实战5 -- 天气查询APP重构之状态管理(ScopedModel)相关推荐

  1. 使用Flutter编写一个简单的天气查询App

    使用Flutter编写一个简单的天气查询App Flutter项目目录分析 入口函数 home:主页面 编写天气应用 网络请求 数据解析 布局编写 Flutter里基础的Widget 上 中 下 Fl ...

  2. Flutter实战之(Clubhouse App)

    flutter_ClubHouse 课程安排 每日一更, 最后达到的效果是1:1 项目简介 "Clubhouse"(俱乐部会馆)的音频聊天应用程序日前火了.这款社交软件的功能相对单 ...

  3. 预报精准的天气查询APP开发原理是什么

    在互联网还不发达的时候,人们看天气预报只能从电视上获取,而且每晚都要坐等七点半新闻联播后,非常不方便,除此之外央视的天气预报不能将全国所有地区的天气都报道出来,只能报道一些省会城市的天气,所以如果你待 ...

  4. Flutter实现天气查询App

    该项目是一个Flutter项目,适合新手,运用了很多的常见组件和布局. 项目特点就是简洁,好理解,运用第三方API实现天气的查询. 适用范围: 1.用于完成学校Flutter作业的朋友. 2.需要一个 ...

  5. “Rimon天气”Android天气查询软件项目总结

    "Rimon天气"是我在自学Android软件开发一段时间后,以郭霖写的<第一行代码>书中的天气查询软件"酷欧天气"为参考,改写的天气查询app.与 ...

  6. Flutter实战(一)写一个天气查询的APP

    先上效果图: 代码github地址:github.com/koudle/GDG_- 1.创建工程 在Android Studio中,File -> New ->New Flutter Pr ...

  7. Kotlin最佳项目实战——欧瑞天气App

    项目实战--欧瑞天气App 到现在为止,我们已经学习了绝大多数Kotlin的核心技术以及如何用Kotlin开发Android App,也编写过大量的程序,但还没有设计过一款完整的App,本章将满足读者 ...

  8. 查python的软件_Python制作天气查询软件【python实战必学】

    在这里插入图片描述 以前,公众号分享了如何使用 PyQt5 制作猜数游戏和计时器,这一次,我们继续学习:如何使用 PyQt5 制作天气查询软件. 如需获取源代码和 exe 文件,请在微信公众号Pyth ...

  9. 仿网易新闻APP(四)——标题栏之本市天气(百度定位与车联网之天气查询)

    废话不多说,上图: 下面用到的知识有,百度定位及车联网API的使用,当然车联网API看起来高大上,其实我们这里只用来获取车联网中的天气查询功能.其他的功能还有渐变动画及缩放动画,以及定时更新天气及定位 ...

最新文章

  1. nefu 628 Garden visiting
  2. Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
  3. Get Started with Omni-Channel
  4. 操作多个表_6_生成笛卡尔积
  5. ubuntu运行python ide_在Ubuntu-16.04中安装Python可视化IDE——Spyder
  6. java插入排序_Java程序要插入排序
  7. python高级语法装饰器_Python高级编程——装饰器Decorator超详细讲解上
  8. 关于一些html和css2的知识点
  9. WINDOWS SERVER 2008/2008 R2/2012 最大内存支持
  10. java获取运行时对象,java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构...
  11. 聊一聊Go中channel的行为
  12. 利用MySQL存储过程分割字符串
  13. 华为Mate 20 X 5G版打通5G电话:音质饱满画面清晰
  14. asp小偷转html,ASP “小偷”程序(抓取程序)
  15. 昨晚做了个flash
  16. Linux驱动开发基础
  17. 如何对接泡椒云,给你的Auto.js脚本增加卡密验证功能?详细教程
  18. BeX5创建w文件窗口显示不齐
  19. labelcommand打印条码_Zebra条码打印机编程命令
  20. ST Visual Programmer(STVP)给STM8系列芯片烧录程序方法

热门文章

  1. 网络安全统计显示XSS和过时的软件是主要问题
  2. 挂载硬盘报错无法挂载、分区只读的解决方法
  3. linux 多网卡多路由表实现策略路由
  4. 《数据库系统概念》20-恢复系统
  5. Lua之table(表)
  6. Teraco公司投资9000万美元扩建其在南非数据中心
  7. Another FTP daemon is already running?
  8. sourceinsight安装记录
  9. PowerShell定时记录操作系统行为
  10. linux 各用户内存_Linux用户空间与内核空间(理解高端内存)