Dio網(wǎng)絡封裝以及數(shù)據(jù)轉(zhuǎn)模型

一、為什么需要封裝Dio

1、遷移代碼

當組件庫中的方法發(fā)生改變,需要遷移的時候,如果有多處地方用到,那么需要對使用到的每個文件都進行修改,非常的繁瑣而且很容易出問題。

2、請求庫切換

當不需要Dio庫的時候,我們可以試隨時方便切換到別的網(wǎng)絡庫。

3、統(tǒng)一配置

因為一個應用程序基本都是統(tǒng)一的配置方式,所以我們可以針對攔截器 、轉(zhuǎn)換器 、 緩存 、統(tǒng)一處理錯誤 、代理配置、證書校驗 等多個配置進行統(tǒng)一管理。

二、使用單利模式進行Dio封裝

1、為什么使用單例模式?

每個頁面都會在進行網(wǎng)絡請求,如果每次都要初始化一個dio,那么會增加系統(tǒng)不必要的開銷,而使用單例模式對象一旦創(chuàng)建每次都是訪問同一個對象,不會再實例化對象。

2、創(chuàng)建單例類
import 'package:dio/dio.dart';
class HttpRequest {
  static final BaseOptions options = BaseOptions(baseUrl: "");

  static final Dio dio = Dio(options);

  static Future<T> request<T>(String url,
      {String method, Map<String, dynamic> params, Interceptor inter}) async {
    // 1.請求的單獨配置
    Options options = Options(method: method);
    options.headers = httpHeaders;
//    // 2.添加第一個攔截器
//    Interceptor dInter =
//        InterceptorsWrapper(onRequest: (RequestOptions options) {
//      // 1.在進行任何網(wǎng)絡請求的時候, 可以添加一個loading顯示
//
//      // 2.很多頁面的訪問必須要求攜帶Token,那么就可以在這里判斷是有Token
//
//      // 3.對參數(shù)進行一些處理,比如序列化處理等
//      print("攔截了請求");
//      return options;
//    }, onResponse: (Response response) {
//      print("攔截了響應");
//      return response;
//    }, onError: (DioError error) {
//      print("攔截了錯誤");
//      return error;
//    });
//
//    List<Interceptor> inters = [dInter];
//    if (inter != null) {
//      inters.add(inter);
//    }
//
//    dio.interceptors.addAll(inters);
    // 3.發(fā)送網(wǎng)絡請求
    try {
      Response response =
          await dio.request(url, data: params, options: options);
      return response.data;
    } on DioError catch (e) {
      return Future.error(e);
    }
  }
}

const httpHeaders = {
  'Content-Type': 'application/json',
  'X-LC-Id': 'a4Cj1Hm5aMrdhob6xGw71B5A-gzGzoHsz',
  'X-LC-Key': 'XQaL1tUQC0DCQxBA9fpoR21C',
};
3、方法調(diào)用
   HttpRequest.request(url, method: 'GET').then((res) {
      var list = new GHAddressModel.fromJson(res).results;
      setState(() {
        this._list = list;
      });
    });
/// 收貨地址列表
class GHAddressList extends StatefulWidget {
  @override
  _GHAddressListState createState() => _GHAddressListState();
}

class _GHAddressListState extends State<GHAddressList> {
  /// 地址列表
  var _list = [];
  GlobalKey _easyRefreshKey = new GlobalKey();
  _getAddressList() async {
    //addressDetails
    //shopAddress
    var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopAddress";
    var c = Uri.encodeComponent('-createdAt');
    var d = Uri.encodeComponent('李');
    url = url + '?' + "order=" + c;

    HttpRequest.request(url, method: 'GET').then((res) {
      var list = new GHAddressModel.fromJson(res).results;
      setState(() {
        this._list = list;
      });
    });
  }

  void initState() {
    super.initState();
    this._easyRefreshKey.currentState;
  }

  void deactivate() {
    // 返回到當前頁刷新
    var bool = ModalRoute.of(context).isCurrent;
    if (bool) {
      this._getAddressList();
    }
  }

  Widget ListItem(Results results) {
    return InkWell(
      onTap: () {},
      child: Container(
        margin: EdgeInsets.only(top: 5, bottom: 5),
        width: ScreenAdaper.getScreenWidth(),
        child: Column(
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Row (
                  children: <Widget>[
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Container(
                          child: Row(
                            children: <Widget>[
                              Container(
                                width:50,
                                child: Text(
                                  results.name,
                                  overflow: TextOverflow.ellipsis,
                                  style:TextStyle(
                                    fontSize: 18,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ),
                              SizedBox(
                                width: 10,
                              ),
                              Container(
                                child: Text(
                                  results.phone,
                                  style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),
                                ),
                              ),
                            ],
                          ),
                        ),
                        Container(
                          width: ScreenAdaper.getScreenWidth() - 20 - 20 - 30,
                          child: Text(
                            results.province +
                                results.city +
                                results.area +
                                results.detailsAddress,
                            style: TextStyle(fontSize: 14, color: Colors.black54),
                          ),
                        ),
                      ],
                    )
                  ],
                ),
                GestureDetector(

                  onTap: () {
                    Navigator.pushNamed(context, '/GHAddressEdit', arguments: {
                      'name': "${results.name}",
                      'zone': "${results.zone}",
                      'detailsAddress': "${results.detailsAddress}",
                      'phoneNumber': results.phone,
                      'objectId': results.objectId,
                    });
                  },
                  child: Container(
                    child: Icon(
                      Icons.edit,
                      size: 30,
                    ),
                  ),
                ),
              ],
            ),
            Divider(),
          ],
        )
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    ScreenAdaper.init(context);
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          TextButton(
            onPressed: () {
              Navigator.pushNamed(context, '/GHAddressEdit');
            },
            child: Icon(Icons.add),
          )
        ],
        title: Text("地址管理"),
      ),
      body: Container(
          padding: EdgeInsets.all(20),
          child: EasyRefresh(
            firstRefresh: true,
            key:_easyRefreshKey,
            onRefresh: () async {
              await this._getAddressList();
            },
            onLoad: () async {
              await this._getAddressList();
            },
            child: ListView.builder(
              itemBuilder: (context, index) {
                return ListItem(this._list[index]);
              },
              itemCount: this._list.length,
            ),
          )),
    );
  }
}

三、數(shù)據(jù)轉(zhuǎn)模型

我們當然不能手寫來實現(xiàn),我們使用quickType來進行轉(zhuǎn)化。
數(shù)據(jù)請求后,轉(zhuǎn)模型

   HttpRequest.request(url, method: 'GET').then((res) {
      var list = new GHAddressModel.fromJson(res).results;
      setState(() {
        this._list = list;
      });
    });

GHAddressModel類型

class GHAddressModel {
  List<Results> results;

  GHAddressModel({this.results});

  GHAddressModel.fromJson(Map<String, dynamic> json) {
    if (json['results'] != null) {
      results = new List<Results>();
      json['results'].forEach((v) {
        results.add(new Results.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.results != null) {
      data['results'] = this.results.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Results {
  String province;
  String area;
  String city;
  String detailsAddress;
  String remark;
  String zone;
  String phone;
  String userId;
  String objectId;
  String updatedAt;
  String createdAt;
  String name;
  String isDefault;
  Where where;

  Results(
      {this.detailsAddress,
        this.remark,
  this.province,
  this.area,
  this.city,
        this.zone,
        this.phone,
        this.userId,
        this.objectId,
        this.updatedAt,
        this.createdAt,
        this.name,
        this.isDefault,
        this.where});

  Results.fromJson(Map<String, dynamic> json) {
    detailsAddress = json['detailsAddress'];
    if (detailsAddress == null) {
      detailsAddress = "暫無地址";
    }
    remark = json['remark'];
    zone = json['zone'];
    if (zone == null) {
      zone = "暫無地址";
    }
    phone = json['phone'];
    if (phone == null) {
      phone = "13800000000";
    }
    userId = json['userId'];
    objectId = json['objectId'];
    updatedAt = json['updatedAt'];
    createdAt = json['createdAt'];
    province = json['province'];
    city = json['city'];
    area = json['area'];
    name = json['name'];
    if (name == null) {
      name = "沒有設置";
    }
    isDefault = json['isDefault'];
    where = json['where'] != null ? new Where.fromJson(json['where']) : null;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['detailsAddress'] = this.detailsAddress;
    data['remark'] = this.remark;
    data['zone'] = this.zone;
    data['phone'] = this.phone;
    data['userId'] = this.userId;
    data['objectId'] = this.objectId;
    data['updatedAt'] = this.updatedAt;
    data['createdAt'] = this.createdAt;
    data['name'] = this.name;
    data['isDefault'] = this.isDefault;
    data['province'] = this.province;
    data['city'] = this.city;
    data['area'] = this.area;


    if (this.where != null) {
      data['where'] = this.where.toJson();
    }
    return data;
  }
}

class Where {
  String token;
  String userId;
  Where({this.token, this.userId});
  Where.fromJson(Map<String, dynamic> json) {
    token = json['token'];
    userId = json['userId'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['token'] = this.token;
    data['userId'] = this.userId;
    return data;
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容