Flutter 通过API获取网络数据并解析

首先通过API获取网络数据这个过程是耗时的,所以我们需要进行异步操作,使用Dart语言完成异步可以参考如下的文章

https://www.jianshu.com/p/f2f7634b602c

1.网络请求

直接进入正题,首先我进行网络请求是通过一个工具类,大家可以直接使用

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

class NetUtils {
  static void get(String url, Function callback, {Map<String, String> params, Function errorCallback}) async {
    if (params != null && params.isNotEmpty) {
      StringBuffer sb = new StringBuffer("?");
      params.forEach((key, value) {
        sb.write("$key" + "=" + "$value" + "&");
      });
      String paramStr = sb.toString();
      paramStr = paramStr.substring(0, paramStr.length - 1);
      url += paramStr;
    }
//    print("$url");
    try {
      http.Response res = await http.get(url);
      if (callback != null) {
        callback(res.body);
      }
    } catch (exception) {
      if (errorCallback != null) {
        errorCallback(exception);
      }
    }
  }
  
  static void post(String url, Function callback, {Map<String, String> params, Function errorCallback}) async {
    try {
      http.Response res = await http.post(url, body: params);
      if (callback != null) {
        callback(res.body);
      }
    } catch (e) {
      if (errorCallback != null) {
        errorCallback(e);
      }
    }
  }
}

我现在使用一下,这个data就是返回的Gson字段

    NetUtils.get(url, (data) {
   
    }, errorCallback: (e) {
      print("network error: $e");
    });

2.解析Gson字段

虽然获取了Gson字段,但是我们还不能获取我们想要的数据,这样和java一样,需要解析Gson字段,这个flutter有相关的API实现了,我们需要导一下包,虽然这个包在NetUtil导入过,但是flutter不能间接导包

import 'dart:convert';
然后使用
    NetUtils.get(url, (data) {
      if (data != null) {
        var obj = json.decode(data);
        if (obj['error'] == false) {
          //print(obj);


          setState(() {
            MyApp.text = obj['results'][0]['desc'];
            if (MyApp.text==null){
              MyApp.text=' ';
            }
          });
        }
      }
    }, errorCallback: (e) {
      print("network error: $e");
    });

3.完整的例子

就是通过干货集中营的API获取网络数据,将其中一个分享的标题显示出来。

这里要注意的是非交互型控件StatelessWidget是不能刷新的,而网络数据获取后需要刷新控件显示,所以我们需要自己自定义一个交互型控件,这个可以参考如下文章

https://blog.csdn.net/z979451341/article/details/80817609

好了,大家看代码

import 'dart:async';

import 'package:flutter/material.dart';
import 'dart:convert';
import 'NetUtils.dart';
import 'AndroidBean.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  static String text='Hello World';

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: ParentWidget(),

        ),
      ),
    );
  }





}

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => new _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;


  @override
  Widget build(BuildContext context) {
    getNetData();
    return new Container(
        child: new Text(MyApp.text)
    );
  }


  getNetData() async {
    var url = 'http://gank.io/api/data/Android/10/1';
    NetUtils.get(url, (data) {
      if (data != null) {
        var obj = json.decode(data);
        if (obj['error'] == false) {
          //print(obj);


          setState(() {
            MyApp.text = obj['results'][0]['desc'];
            if (MyApp.text==null){
              MyApp.text=' ';
            }
          });
        }
      }
    }, errorCallback: (e) {
      print("network error: $e");
    });
  }


}
AndroidBean.dart
class AndroidBean{
  String desc;
  List<String> images;
  String url;
  String who;


  static List androidData;
}

4.最后

我要做一个比较完整的app,敬请期待




猜你喜欢

转载自blog.csdn.net/z979451341/article/details/80899980