flutter网络请求数据

企业微信截图_dbd20a6e-a34b-47a7-b6fa-90f67355e9f1

 一、安装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(() {}); 
}

 

posted @ 2026-05-08 17:24  Wolf_Stark  阅读(8)  评论(0)    收藏  举报