Flutter學習(7)——網絡請求框架Dio簡單使用


原文地址: Flutter學習(7)——網絡請求框架Dio簡單使用 | Stars-One的雜貨小窩

之前的Flutter學習系列都是在個人博客上發布的,感興趣可以去看看,就不搬過來了

網絡請求一般APP都是需要的,在Flutter中,目前比較流行的網絡請求框架是Dio,是Flutter中文網推出的,也算是國人開發的👍

本文主要是講解如何簡單使用Dio的get請求來獲取數據,並使用Flutter中的listview進行展示

關於listview在之前已經講過使用方法😃 不清楚的同學可以先去看看Flutter學習(6)——Tab導航與ListView使用 | Stars-One的雜貨小窩

注: 本文基於Fluter1.2版本,只講解了Dio的get請求,之后再看看有沒有時間補充一波詳細的使用和例子吧,本篇代碼保存在github

Dio介紹

dio是一個強大的Dart Http請求庫,支持Restful API、FormData、攔截器、請求取消、Cookie管理、文件上傳/下載、超時、自定義適配器等...

實現過程

PS:引入Dio框架,我們只需要在pubspec.yaml文件中的dependencies標簽下面寫即可

dio: ^3.0.0

項目添加Dio框架依賴

1.get請求數據

這里,我們使用最為簡單的get請求方式來獲取數據,接口的話我們使用郭霖大佬提供的API接口http://guolin.tech/api/china,我們可以使用瀏覽器直接訪問,來看看獲取的數據,如下圖所示

返回的數據是各大城市的相關數據,待會我們可以使用列表把城市名顯示出來即可

請求接口的代碼如下

void getCityData() async {
    Response response;
    var dio = Dio();
    response = await dio.get('http://guolin.tech/api/china');
    print(response.data.toString());
}

因為這里是數據是從接口獲取的,數據為動態的,這里我們的頁面得使用StatefulWidget,則是在State類初始化initState方法的時候調用接口

代碼跑起來,進到頁面,發現報錯了😕 錯誤如下所示:

百度一看,是因為Android高版本不支持http協議的緣故,所以,按照之前的老套路,加個xml配置,調整即可,具體可參考Android 9 網絡請求失敗 | Stars-One的雜貨小窩

按照上面的步驟配置后,再來試下(注意需要停止APP后重新進行編譯,然后再點debug或run的圖標,使用熱重載是不會起作用的)

ok,成功調通​,​數據​已經​打印​出來​了:happy:

2.實體類創建

之前我們Android開發的時候,使用的是Gson解析json字符串,將json字符串轉為對應的實體類,好方便我們取值,這里,flutter同樣也是

這里推薦使用個插件JsonToDart進行實體類的生成,插件地址

安裝好插件后,我們要使用的話,可以右鍵,然后懸着具體菜單即可新建即可,這里我是建了個model文件夾,右鍵model文件夾, New -> Json To Dart

把json字符串輸入進去,輸入類名,之后點擊Generate即可生成一個dart的實體類文件

以往Android開發中我們是使用Gson等框架,把json字符串轉為實體類

而在flutter中,由於其內置有Json類型的數據,所以不必要再引入其他框架,使用jsonDecode方法即可

小提示:如果直接復制,jsonDecode可能會報錯,因為還沒有導入,可以光標選擇jsonDecode,按下alt+enter,選擇import開頭的那個菜單即可自動導入

我們稍微改下代碼,如下:

void getCityData() async {
    Response response;
    var dio = Dio();
    response = await dio.get('http://guolin.tech/api/china',options: Options(responseType: ResponseType.plain));
    var list = jsonDecode(response.data);
    var cityList = list.map((m) => new CityModel.fromJson(m)).toList();
    print(cityList);
}

這里我們可以看到代碼的第五行,傳了個options參數,options是為了設置返回的類型數據,如果沒有這個的話,Dio會自動將返回的數據轉為Json類型的對象

但是由於現在接口返回的一個Json數組的字符串,導致無法解析成功(平常接口都是一個json的字符串,郭霖大佬寫得..😅 )

所以得采用此方法進行解析,之后將數據轉為List類型,里面的每個數據都是實體類

3.列表展示

展示就比較簡單了,我們使用ListView即可,不過,需要注意的是,得提前在State類中定義好一個List數組

接口請求到數據之后,更新此List數組里的數據即可達到更改UI的操作(注意使用setState()方法哦😎)

void getCityData() async {
    var dio = Dio();
    Response response = await dio.get('http://guolin.tech/api/china',
        options: Options(responseType: ResponseType.plain));
    var list = jsonDecode(response.data);

    var cityList = list.map((m) => new CityModel.fromJson(m)).toList();
    //注意使用setState方法
    setState(() {
      //this.list是在State類中定義的
      this.list.addAll(cityList);
    });
}

效果圖

源碼

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/model/city_model.dart';
import 'package:webview_flutter/webview_flutter.dart';

import 'MyMaterialPage.dart';

class DioTestPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return DioTestState();
  }
}

class DioTestState extends State<DioTestPage> {
  List list = [];

  @override
  Widget build(BuildContext context) {
    return MyMaterialPage("Dio獲取數據及展示", _listView());
  }

  @override
  void initState() {
    getCityData();
  }

  void getCityData() async {
    var dio = Dio();
    Response response = await dio.get('http://guolin.tech/api/china',
        options: Options(responseType: ResponseType.plain));
    var list = jsonDecode(response.data);

    var cityList =
    list.map((m) => new CityModel.fromJson(m)).toList();
    setState(() {
      this.list.addAll(cityList);
    });

  }

  Widget _listView() {
    return new ListView.builder(
      //listview的子項item數量
      itemCount: list.length,
      //內邊距
      padding: new EdgeInsets.all(5.0),
      itemBuilder: (BuildContext context, int index) {
        //返回每個子項item的widget
        //城市名
        return _listItemView(list[index].name);
      },
    );
  }

  Widget _listItemView(String name) {
    return Row(
      children: [
        Center(
          child: Text(name),
        ),
      ],
    );
  }
}

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM