flutter网络请求数据

一、安装dio
flutter pub add dio
二、定义常量数据 (constants - index.dart)
// 全局的常量 class GlobalConstants { // static const String BASE_URL = "https://meikou-api.iteima.net"; static const String BASE_URL = "http://127.0.0.1:8080"; static const int TIME_OUT = 10; static const String SUCCESS_CODE = "1"; } // 存放请求地址接口的常量 class HTTPCONSTANTS { static const BANNER_LIST = "/home/banner"; }
三、封装网络工具、基础地址、拦截器(utils - DioRequest.dart)
* DioRequest
class DioRequest { final _dio = Dio(); // 基础地址拦截器 DioRequest() { _dio.options ..baseUrl = GlobalConstants.BASE_URL ..connectTimeout = Duration(seconds: GlobalConstants.TIME_OUT) ..sendTimeout = Duration(seconds: GlobalConstants.TIME_OUT) ..receiveTimeout = Duration(seconds: GlobalConstants.TIME_OUT); // 拦截器 _addInterceptor(); } }
* DioRequest - _addInterceptor();
void _addInterceptor() { _dio.interceptors.add(InterceptorsWrapper( onRequest: (request, handler) { handler.next(request); }, onResponse: (response, handler) { // http 状态码 200 300 if (response.statusCode! >= 200 && response.statusCode! < 300) { // 成功放行 handler.next(response); return; } handler.reject(DioException(requestOptions: response.requestOptions)); }, onError: (error, handler) { handler.reject(error); }, )); }
* DioRequest - 请求方法封装 、进一步解构
Future<dynamic> get(String url, {Map<String, dynamic>? params}) {
return _handleResponse(_dio.get(url, queryParameters: params));
}
// 进一步处理返回结果的函数
Future<dynamic> _handleResponse(Future<Response<dynamic>> task) async {
try {
Response<dynamic> res = await task;
final data = res.data as Map<String, dynamic>; // 接口真正返回的数据
if (data["code"] == GlobalConstants.SUCCESS_CODE) {
// 才认定 http状态和业务状态均正常 就可以正常的放行通过
return data["result"];
}
// 抛出异常
throw Exception(data["msg"] ?? "加载数据异常");
} catch(e) {
throw Exception(e);
}
}
* 工具声明为单例
// 单例对象 final dioRequest = DioRequest(); // dio请求工具发出请求 返回的数据 Response<dynamic>.data // 把所有的接口的data解放出来 拿到真正数据 要判断业务状态码 是否等于 1
五、类方法转化动态类型到对象类型 (viewmodel - 页面名.dart)
class BannerItem { String id; String imgUrl; BannerItem({required this.id, required this.imgUrl}); // 扩展一个工厂函数 一般用factory来声明 一般用来创建实例对象 // 语法规则 - 类名必须和当前类一样(BannerItem) // factory 类名.自定义名字(参数) { // return 类名(...) // } // factory关键字构造函数 // factory BannerItem.fromJSON 的作用:把接口返回的 Map(JSON) → 自动转成 Dart 对象 BannerItem factory BannerItem.fromJSON(Map<String, dynamic> json) { // 必须返回一个BannerItem对象 return BannerItem( id: json["id"] ?? "", imgUrl: json["imgUrl"] ?? "" ); } }
六、封装请求工厂API
Future<List<BannerItem>> getBannerItemAPI() async { // 返回结果 // as 作用:把一个泛泛的类型,强行转换成你明确知道的具体类型 // map方法是迭代处理 - 返回一个Iterable<BannerItem> - 用 .toList()来进行转化 return ((await dioRequest.get(HTTPCONSTANTS.BANNER_LIST)) as List).map((item) { return BannerItem.fromJSON(item as Map<String, dynamic>); }).toList(); }
七、初始化数据更新 - 页面
// 页面的方法-这是数据渲染部分
@override void initState() { // TODO: implement initState super.initState(); _getBannerList(); } void _getBannerList() async { _bannerList = await getBannerItemAPI(); // _bannerList是类属性,接收加载的数据
print("*********************_bannerList=${_bannerList}"); setState(() {});
}

浙公网安备 33010602011771号