使用 Provider 管理 Flutter 应用状态 (下)
前言
紧接上篇,对于一个代办事项的新增,修改,删除功能都已经完成了,但是数据都是保存在内存中的,重新启动应用数据就重置了,为了存储数据可以将数据存到手机的存储里面或者存到远程服务器上,本文就实现如何使用 dio 将数据存到服务器
开发准备
在 pubspec.yaml
添加 dio 依赖;一个存储数据的服务,我用的是 jsonbox
1 | dependencies: |
配置 dio
由于这个应用只有一个服务地址,所以创建一个 dio 的单例来进行请求就很好了,新建一个 request.dart 文件配置 dio,使用一个函数返回创建的 dio 实例
- 设置基础的请求地址
- 设置请求超时时间
- 设置在调试控制台输出请求响应体方便查看请求
基本设置下就可以用了,其它设置可以查看 dio 的文档
1 | import 'package:dio/dio.dart'; |
修改 Todo 模型
由于需要从服务器上获取 todo 数据,服务返回的数据是 json 格式,所以需要在拿到数据的时候将单个 todo 的 json 数据转成 Todo 实例,新建一个 model/todo.dart 文件,比之前多的是两个方法而已,fromJson
这个工厂函数作用是使用 json 数据实例化一个 Todo,toJson
方法用来将一个 Todo 转成一个 Map 结构的数据
如果一个模型的字段较少可以手写,但是当字段较多比较复杂的时候就需要使用工具来帮助生成代码了,我使用的是 quicktype 这个工具
1 | class Todo { |
发送请求
配置好 dio 就可以在 todos.dart 向服务器发送请求了,修改 store/todos.dart,给 Todos 类添加了一个 _dio 属性用来发送请求,一个 getTodos 方法用来获取全部 todo 的列表数据,然后修改 addTodo,removeTodo,editTodo 方法使用 _dio 向服务器发送 post,delete,put 请求。
需要注意的一点是将 json 转换成实例的问题,很容易就会出现类似
1 | type 'List<dynamic>' is not a subtype of type 'List<Todo>' |
这种错误,这种都是类型转换的问题,我看了一篇文章后才算弄懂了一点 parsing-complex-json-in-flutter
1 | import 'package:dio/dio.dart'; |
使用数据
有了数据后就可以在列表页使用了,由于现在数据是从服务器返回的,会有请求耗时,所以需要使用 FutureBuilder
这个部件渲染列表,FutureBuilder
需要一个设置一个 future 来判断状态,这里自然是 Todos 类的 getTodos
方法返回的 Future 对象,然后 builder 就是一个函数,有两个参数,一个是 context 上下文对象,一个是 snapshot 对象,表示的是这个 future 的状态。
在 builder 方法里面用一个 switch 语句判断这个 future 的状态,根据状态返回需要渲染的部件,有以下几种状态 none(状态不存在),active(运行中),waiting(等待中),done(完成),如果都不匹配就,返回一个 null 值。
1 | import 'package:flutter/material.dart'; |
修改按钮
接下来就是需要修改新增,编辑,删除代办的按钮了,同理由于现在需要跟服务端进行通信,所以需要根据请求状态来处理逻辑,主要的修改就是使用 async/await
语法等到一个请求完成后,根据返回值进行处理。
添加 Todo 按钮
1 | import 'package:flutter/material.dart'; |
编辑 Todo 按钮
1 | import 'package:flutter/material.dart'; |
删除 Todo 按钮
1 | import 'package:flutter/material.dart'; |
结语
至此所有的数据都存储在服务器上了,重启应用数据也会从服务器上获取了。