【Flutter 3-3】Flutter進階教程——http請求和FutureBuilder

作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)

異步請求

在移動開發(fā)過程中很多時候我們都需要依賴異步請求數(shù)據(jù)然后再來刷新UI呵燕。在用戶打開界面的時候,先給出一個Loading提示,等數(shù)據(jù)請求完成后偶垮,我們再把數(shù)據(jù)展示在頁面上结蟋,這是很常見的操作招刹。

異步請求的好處就是不會阻塞主線程,用戶雖然在“等”审丘,但是頁面不會卡死吏够。
同步請求不適應(yīng)于這種情況,同步請求會出現(xiàn)頁面卡死現(xiàn)象滩报,此時用戶不能點擊(即使點擊也沒有效果)锅知,體驗非常不好。
所以大多數(shù)時候我們都是使用異步請求來獲取數(shù)據(jù)

http 庫

在Flutter中脓钾,我們可以用http庫來做網(wǎng)絡(luò)請求售睹,它支持異步請求,并且有良好的API接口
使用http庫的步驟:

  • 在項目中可训,打開pubspec.yaml文件
  • 找到dependencies字段昌妹,在下面添加http: ^0.12.2,其中0.12.2是版本號
  • 然后保存pubspec.yaml 并執(zhí)行pub get命令把我們要使用的第三方庫下載下來

具體 pub get命令的使用在之前的文章有介紹過

2021_02_02_http_request_yaml

然后在要使用http庫的文件里面引入頭文件

import 'package:http/http.dart' as http;

發(fā)送http請求的代碼也比較簡單握截,我們這里以get請求為例

http.get("https://cdn.jsdelivr.net/gh/johnson8888/blog_pages/images/request_demo_test.json");

只要傳入要請求的地址即可飞崖,這里的URL地址是我自己上傳的測試文件。

http 異步請求返回結(jié)果

前面我知道http庫發(fā)送請求是支持異步的谨胞,那么異步請求的返回結(jié)果我們該如何接收呢固歪?

  • 通過then函數(shù)獲取,在get請求之后我們可以直接跟上then函數(shù)來作為回調(diào)胯努,在回調(diào)內(nèi)部可以獲取到請求的結(jié)果
http.get(getURL).then((value) {
  print(value);
});

這樣寫確實很方便牢裳,但當我們的網(wǎng)絡(luò)請求很多,并且一個網(wǎng)絡(luò)請求依賴另外一個網(wǎng)絡(luò)請求的時候叶沛,這個時候就會多個回調(diào)函數(shù)嵌套在一起(又稱為回調(diào)地獄)蒲讯,代碼就會顯得很凌亂,很不適合Debug恬汁。

  • 使用await來接收異步操作的結(jié)果
var data = await http.get(getURL);

這樣寫代碼就比上面的代碼清爽多了
但是需要注意的是伶椿,如果函數(shù)內(nèi)部有被await修飾的方法,那么函數(shù)應(yīng)該被async來修飾氓侧,并且返回值需要被Future修飾脊另,Future是一個延時計算的對象,在被await修飾的函數(shù)返回的時候才能拿到Future的具體值约巷。
示例入下:

Future<Map> getData() async {
  var data = await http.get(getURL);
  return data.body; 
}

刷新頁面

我們前面已經(jīng)知道:調(diào)用setState()函數(shù)可以刷新頁面偎痛,所以在http請求之后我們調(diào)用setState()函數(shù)即可刷新頁面

http.get(getURL).then((value) {
  print(value);
  var data = jsonDecode(data.body);
  setState(() {
    /// 此處執(zhí)行刷新頁面的代碼
  });
});

使用FutureBuilder來刷新頁面

setState()固然是可以刷新頁面,但是當我們頁面內(nèi)有多個網(wǎng)絡(luò)請求的時候独郎,就會不停的調(diào)用setState()來全量刷新頁面踩麦,顯然這就有點冗余枚赡。
Flutter為我們提供了更好的方式來實現(xiàn)獲取數(shù)據(jù)并且刷新UI的操作,那就是FutureBuilder
來看它的初始化方法

const FutureBuilder({
  /// key
  Key key,
  /// 異步的操作
  this.future,
  /// 初始化數(shù)據(jù)
  this.initialData,
  /// 構(gòu)建UI的函數(shù)
  @required this.builder,
}) 

由構(gòu)造函數(shù)可見谓谦,我們需要傳入future參數(shù)贫橙,也就是我們的耗時操作函數(shù),還需要傳入builder函數(shù)
builder方法里可以捕捉到兩個參數(shù)BuildContext contextAsyncSnapshot snap
其中snap的屬性會攜帶future的耗時函數(shù)的返回值反粥,也就是說:在耗時操作函數(shù)返回結(jié)果之后卢肃,我們可以在builder方法內(nèi)獲取到這一返回值。
所以上面的請求我們也可以這么來實現(xiàn):

FutureBuilder(
  future: getData(),
  builder: (BuildContext context, AsyncSnapshot snap) {
    /// 如果沒有數(shù)據(jù) 我們就顯示loading頁面
    if (snap.hasData == false) {
      return CircularProgressIndicator();
    } else {
    /// 如果獲取到了數(shù)據(jù) 我們就初始化一個 ListView來展示獲取到的數(shù)據(jù)
      var dataSource = snap.data["tracks"];
      return ListView.builder(
        itemCount: dataSource.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(dataSource[index]["title"]),
            subtitle: Text(dataSource[index]["cover"]),
          );
        },
      );
    }
  },
),

在獲取到數(shù)據(jù)之后才顿,我們通過ListView.builder來構(gòu)建一個ListView并返回莫湘,此時就完成了刷新UI的工作

我這里寫的比較簡單,只是用hasData來做為判斷的依據(jù)
其實還有更優(yōu)雅的做法:使用snap的另一個屬性connectionState

enum ConnectionState {
  /// 沒有異步任務(wù)郑气,
  none,
  /// 異步任務(wù)正在等待
  waiting,
  /// 異步任務(wù)正在執(zhí)行 或者 數(shù)據(jù)正在傳輸
  active,
  /// 異步任務(wù)已經(jīng)終止.
  done,
}

我們也可以在connectionStatedone的時候在來判斷是否存在數(shù)據(jù)
如果存在就展示數(shù)據(jù)幅垮!

想體驗以上的示例的運行效果,可以到我的Github倉庫項目flutter_app->lib->routes->http_page.dart查看尾组,并且可以下載下來運行并體驗忙芒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市演怎,隨后出現(xiàn)的幾起案子匕争,更是在濱河造成了極大的恐慌,老刑警劉巖爷耀,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甘桑,死亡現(xiàn)場離奇詭異,居然都是意外死亡歹叮,警方通過查閱死者的電腦和手機跑杭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咆耿,“玉大人德谅,你說我怎么就攤上這事∪荩” “怎么了窄做?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長慰技。 經(jīng)常有香客問我椭盏,道長,這世上最難降的妖魔是什么吻商? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任掏颊,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乌叶。我一直安慰自己盆偿,他們只是感情好,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布准浴。 她就那樣靜靜地躺著事扭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兄裂。 梳的紋絲不亂的頭發(fā)上句旱,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天阳藻,我揣著相機與錄音晰奖,去河邊找鬼。 笑死腥泥,一個胖子當著我的面吹牛匾南,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛔外,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛆楞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夹厌?” 一聲冷哼從身側(cè)響起豹爹,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矛纹,沒想到半個月后臂聋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡或南,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年孩等,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片采够。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡肄方,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蹬癌,到底是詐尸還是另有隱情权她,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布逝薪,位于F島的核電站隅要,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翼闽。R本人自食惡果不足惜拾徙,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一靠娱、第九天 我趴在偏房一處隱蔽的房頂上張望踪宠。 院中可真熱鬧,春花似錦、人聲如沸很泊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胚吁。三九已至,卻和暖如春书聚,著一層夾襖步出監(jiān)牢的瞬間唧领,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工雌续, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留斩个,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓驯杜,卻偏偏與公主長得像受啥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鸽心,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容