Flutter學習之旅(五)----網絡請求獲取數據、解析數據和顯示等待動畫

參考官方文章(英文版)

網絡請求是APP開發中至關重要的一步,回想一下Android開發中的Retrofit框架或者Volley框架,iOS開發中AFNetworking框架。如果使用Volley進行網絡請求,我們需要new一個StringRequest請求,在裏面回調成功和失敗的方法,用GsonFormmater等類似工具解析json串,然後將這個請求添加到隊列,這中間要給予用戶友好的提示,即顯示與隱藏加載框,甚至是下拉刷新功能的實現,如果要保持登錄狀態,還需要將Session信息添加到請求的頭部。成熟的網絡請求框架像Volley很容易實現這些功能,Flutter中的網絡請求是否能夠實現這些功能呢,如何實現呢?
這篇文章主要介紹如何在Flutter中進行網絡請求,包括基本的網絡請求,對服務器返回的json進行解析,構造json,加載框顯示與隱藏。

一、完整的網絡請求過程

打開InteliJ IDEA,新建一個Flutter工程,在左側工程結構裏面的pubspec.yaml文件裏面添加網絡請求的依賴

http: '>=0.11.3+12'

將main.dart裏面的代碼全部刪除,然後重新寫我們的代碼,先導包:

import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包

然後獲取http對象

var httpclient=createHttpClient();//獲取http對象

用async…await..發送網絡請求並讀取結果:

_postData() async{
    response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
    print('Response=$response');
  }

上面就是一次完整的網絡請求的核心代碼,好像並不複雜吧?完整的代碼如下,直接複製到main.dart,替換掉原來的代碼即可運行:

import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包
void main(){
  runApp(new MaterialApp(home: new ClickEvent(),));
}
class ClickEvent extends StatefulWidget{
  @override
  _ClickEventState createState() {
    return new _ClickEventState();
  }
}
class _ClickEventState extends State<ClickEvent>{
  var httpclient=createHttpClient();//獲取http對象
  var url='https://api.github.com/';
  var response;
  _postData() async{
    response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
    print('Response=$response');
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(appBar: new AppBar(title: new Text('網絡請求'),),
      floatingActionButton: new FloatingActionButton(child: new Text('獲取數據'),onPressed: _postData),);//點擊後調用網絡請求方法
  }
}

運行結果爲:

這裏寫圖片描述

上面就是https://api.github.com/這個接口返回的json串,至此我們已經能夠從服務器獲取網絡數據了,怎麼樣,比想象中簡單吧。

二、解析服務器返回的json數據

先導入json相關的包

import 'dart:convert';

如果返回的數據結果類似於:

['foo', { 'bar': 499 }]

可以這樣解析

Map data= JSON.decode(response);
data[1]['bar'];

如果返回的數據結構類似於:

{"current_user_url":"https://api.github.com/user"}

可以這樣解析:

Map data= JSON.decode(response);
var url1= data['current_user_url'];

解析結果爲:

current_user_url:https://api.github.com/user

三、等待動畫的顯示與關閉

先新建一個對話框(圓圈)控件,用來顯示,核心代碼是

new CircularProgressIndicator()//這是圓圈對話框,還有條形對話框的。

然後用定時器不斷去回調結果,代碼如下:

class ShowProgress extends StatefulWidget {
  ShowProgress(this.requestCallback);
  final Future<Null> requestCallback;//這裏Null表示回調的時候不指定類型
  @override
  _ShowProgressState createState() => new _ShowProgressState();
}
class _ShowProgressState extends State<ShowProgress> {
  @override
  initState() {
    super.initState();
    new Timer(new Duration(milliseconds: 10), () {//每隔10ms回調一次
      widget.requestCallback.then((Null) {//這裏Null表示回調的時候不指定類型
        Navigator.of(context).pop();//所以pop()裏面不需要傳參,這裏關閉對話框並獲取回調的值
      });
    });
  }
  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new CircularProgressIndicator(),//獲取控件實例
    );
  }
}

點擊“獲取數據”按鈕,將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框,下面代碼功能主要是展示對話框,核心代碼如下:

Future<Null> _myClick()  {
     return showDialog<Null>(
         context: context,
         barrierDismissible: true, // false表示必須點擊按鈕才能關閉
         child:new ShowProgress(_postData())//將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框
     );

完整代碼如下,直接複製到main.dart即可運行:

import 'dart:async';
import 'package:flutter/material.dart';//導入系統基礎包
import 'package:flutter/services.dart';//導入網絡請求相關的包
import 'dart:convert';
void main(){
  runApp(new MaterialApp(home: new ClickEvent(),));
}
class ShowProgress extends StatefulWidget {
  ShowProgress(this.requestCallback);
  final Future<Null> requestCallback;//這裏Null表示回調的時候不指定類型
  @override
  _ShowProgressState createState() => new _ShowProgressState();
}

class _ShowProgressState extends State<ShowProgress> {
  @override
  initState() {
    super.initState();
    new Timer(new Duration(milliseconds: 10), () {//每隔10ms回調一次
      widget.requestCallback.then((Null) {//這裏Null表示回調的時候不指定類型
        Navigator.of(context).pop();//所以pop()裏面不需要傳參,這裏關閉對話框並獲取回調的值
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new CircularProgressIndicator(),
    );
  }
}
////////////上面是對話框控件,下面是按鈕控件/////////////////
class ClickEvent extends StatefulWidget{
  @override
  _ClickEventState createState() {
    return new _ClickEventState();
  }
}
class _ClickEventState extends State<ClickEvent>{
   Future<Null> _myClick()  {
     return showDialog<Null>(
         context: context,
         barrierDismissible: true, // false表示必須點擊按鈕才能關閉
         child:new ShowProgress(_postData())//將網絡請求的方法_postData作爲參數傳遞給ShowProgress顯示對話框
     );
  }
  var httpclient=createHttpClient();//獲取http對象
  var url='https://api.github.com/';
  var response;
  //核心的網絡請求方法
  _postData() async{
    response=await httpclient.read(url);//發送網絡請求,read()表示讀取返回的結果,get()表示不讀取返回的結果
    print('Response=$response');
    Map data= JSON.decode(response);
    var url1= data['current_user_url'];
    print('current_user_url:$url1');
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(appBar: new AppBar(title: new Text('網絡請求'),),
      floatingActionButton: new FloatingActionButton(child: new Text('獲取數據'),onPressed: _myClick),);
  }
}

運行結果爲:

這裏寫圖片描述

從圖中可以看到,收到服務器響應後就關閉了對話框,達到了我們的目的。
上面講解了一次基本的網絡請求,包括獲取數據,解析數據,顯示等待動畫。當然,成熟的網絡框架遠不止這些,還包括緩存處理,超時處理,異常處理,封裝等等,這些我們以後都會涉及到。

如果看完這篇文章您有所收穫,不忘點個贊或者關注一下留個言什麼的,您的鼓勵是我前進的動力,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章