Flutter网络请求,解析json数据,列表展示

实现效果:


image

需要使用到的第三方网络库:dio

在pubspec.yaml中添加第三方库(相当于Android Studio中的build gradle目录)
dio: ^0.0.14 (dio第三方库名,^后面代表版本号,点击packages get后完成依赖)

使用干货提供的JSON数据。
http://gank.io/api/data/

json格式如下:
{
"error": false,
"results": [
{
"_id": "5b3d883f421aa906e5b3c6f1",
"createdAt": "2018-07-05T10:53:51.361Z",
"desc": "2018-07-05",
"publishedAt": "2018-07-05T00:00:00.0Z",
"source": "web",
"type": "\u798f\u5229",
"url": "http://ww1.sinaimg.cn/large/0065oQSqly1fsysqszneoj30hi0pvqb7.jpg",
"used": true,
"who": "lijinshanmx"
}
]
}

第一步:

建立JSON所对应得model类,解析过程在FLModel.formJson()中处理,对应key即可解析,这里注意类型必须对应,否则解析失败,比如返回String类型,你声明时却是int,这里不会自动转换,导致数据无法解析出来。

/解析类

  class FLModle{
     final String _id;
      final String createdAt;
    final String desc;
    final String publishedAt;
    final String source;
    final String type;
    final String url;
    final bool used;
    final String who;

    const FLModle(this._id, this.createdAt, this.desc, this.publishedAt, this.source,
    this.type, this.url, this.used, this.who);

@override
  String toString() {
    return 'FLModle{_id: $_id, createdAt: $createdAt, desc: $desc, publishedAt: $publishedAt, source: $source, type: $type, url:           $url, used: $used, who: $who}';
  }

    FLModle.fromJson(Map json)
    : _id = json['_id'],
    createdAt = json['createdAt'],
    desc = json['desc'],
    publishedAt = json['publishedAt'],
    source = json['source'],
    type = json['publishedAt'],
    url = json['url'],
    used = json['used'],
    who = json['who'];
  }

第二步:

创建一个有状态的组件,继承StatefulWidget,在createState方法中创建我们继承State的组件。

class MeziList extends StatefulWidget{
      @override
      State createState() {
        // TODO: implement createState
        return new MeziSateList();
  }
}

第三步:创建MeziSateList,继承State组件,可通过setState来更新UI,相当于Android中的runOnUI
(此处内代码放在最后一步编写)。

class MeziSateList extends State{
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        }
      }

第四步:

构建网络请求,返回需要的List集合,使用async和await来完成耗时的操作,相当关android中的子线程,Future类似于消息机制(个人观点,只是为了简单理解):

          Future>  _getDate(int pageNum,int pageSize) async{
        List flModels;
        String url = Constant.baseUrl + '福利/$pageSize/$pageNum';
        print(url);
          Response response = await dio.get(url);
          if(response.statusCode== HttpStatus.OK){//响应成功
              flModels = (response.data)['results'] ;
              currentpage = currentpage+1;//加载成功后才可加载下一页
          }else{//出问题
         }
        print(flModels.map((model) {
          return new FLModle.fromJson(model);
        }).toList().length);

        return flModels.map((model) {
          return new FLModle.fromJson(model);
      }).toList();

          }


  Future> feach(int pageNum,int pageSize){
return _getDate(pageNum, pageSize);
  }

第四步:编写加载更多和刷新各自对应的逻辑

//刷新时调用

  Future _refreshData(){

final Completer completer = new Completer();
currentpage = 1;
feach(currentpage, pageSize).then((list) {
  setState(() {
      datas = list;
  });
}).catchError((error) {
  print(error);
});
completer.complete(null);
return completer.future;
  }

//加载更多时调用

  Future _loadMoreData(){

final Completer completer = new Completer();


feach(currentpage, pageSize).then((list) {
  setState(() {
      datas.addAll(list);
  });
}).catchError((error) {
  print(error);
});
completer.complete(null);

return completer.future;
  }

第五步:

创建ScrollController来监听ListView的滑动,需要在initState方法中addListener,并且在dispose中removeListener。

/滑动到底了自动加载更多

  void _scrollListener(){
if(_scrollController.position.pixels==_scrollController.position.maxScrollExtent){
  _loadMoreData();
}
  }

//页面初始化时加载数据并实例化ScrollController

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _refreshData();
    _scrollController = new ScrollController()..addListener(_scrollListener);
  }

   @override
    void dispose() {
      // TODO: implement dispose
    super.dispose();
    _scrollController.removeListener(_scrollListener);
  }

第六步:

创建item并实现点击事件

Widget buildCardItem(BuildContext context,int index){
    final String url = datas[index].url;
    return new GestureDetector(//点击事件
      onTap: (){

       _showPhoto(url);
      },
      child: new Card(
        child: new Container(
          padding: EdgeInsets.all(8.0),
          child: new Image.network(url),
        ),
      ),
    );
  }

最后一步:

构建ListView,数据加载时显示圆环

 @override
  Widget build(BuildContext context) {
    // TODO: implement build
    var content ;
    if(datas.isEmpty){
      content =  new Center(child: new CircularProgressIndicator());;
    }else{
      content = new ListView.builder(
        physics: AlwaysScrollableScrollPhysics(),
        itemCount: datas.length,
        controller: _scrollController,
        itemBuilder: buildCardItem,
      );
    }

    var _refreshIndicator = new RefreshIndicator(
        onRefresh: _refreshData,
      child: content,
    );
    return _refreshIndicator;
  }

完整代码

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'progreess_dialog.dart';
import 'package:easy_app/multi_touch_page.dart';
import 'constant.dart';
//解析类

class FLModle{
  final String _id;
  final String createdAt;
  final String desc;
  final String publishedAt;
  final String source;
  final String type;
  final String url;
  final bool used;
  final String who;

  const FLModle(this._id, this.createdAt, this.desc, this.publishedAt, this.source,
      this.type, this.url, this.used, this.who);

  @override
  String toString() {
    return 'FLModle{_id: $_id, createdAt: $createdAt, desc: $desc, publishedAt: $publishedAt, source: $source, type: $type, url: $url, used: $used, who: $who}';
  }

  FLModle.fromJson(Map json)
  : _id = json['_id'],
    createdAt = json['createdAt'],
    desc = json['desc'],
    publishedAt = json['publishedAt'],
    source = json['source'],
    type = json['publishedAt'],
    url = json['url'],
    used = json['used'],
    who = json['who'];
}

class TabGirlPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
// TODO: implement build
    return new Scaffold(
     body: new MeziList(),
    );
  }

}

class MeziList extends StatefulWidget{
  @override
  State createState() {
    // TODO: implement createState
    return new MeziSateList();
  }
}

class MeziSateList extends State{

  List datas = [];//初始化列表数据源
  int currentpage = 1;//默认当前页
  int pageSize = 10;//每页加载数据


  Dio dio = new Dio();//第三方网络加载库
  ScrollController _scrollController;

  //滑动到底了自动加载更多
  void _scrollListener(){
    if(_scrollController.position.pixels==_scrollController.position.maxScrollExtent){
      _loadMoreData();
    }
  }

//页面初始化时加载数据并实例化ScrollController
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _refreshData();
    _scrollController = new ScrollController()..addListener(_scrollListener);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _scrollController.removeListener(_scrollListener);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    var content ;
    if(datas.isEmpty){
      content =  new Center(child: new CircularProgressIndicator());;
    }else{
      content = new ListView.builder(
        physics: AlwaysScrollableScrollPhysics(),
        itemCount: datas.length,
        controller: _scrollController,
        itemBuilder: buildCardItem,
      );
   }  

    var _refreshIndicator = new RefreshIndicator(
        onRefresh: _refreshData,
      child: content,
    );
    return _refreshIndicator;
  }

  void _showPhoto(String url) {
    Navigator.of(context).push(new PageRouteBuilder(
        opaque: false,
        pageBuilder: (BuildContext context, _, __) {
          return new MultiTouchPage(url);
        },
        transitionsBuilder: (_, Animation animation, __, Widget child) {
          return new FadeTransition(
            opacity: animation,
            child: new RotationTransition(
              turns: new Tween(begin: 0.5, end: 1.0).animate(animation),
              child: child,
            ),
          );
        }));
  }

  Widget buildCardItem(BuildContext context,int index){
    final String url = datas[index].url;
   return new GestureDetector(//点击事件
      onTap: (){
     
        _showPhoto(url);
      },
        child: new Card(
        child: new Container(
          padding: EdgeInsets.all(8.0),
          child: new Image.network(url),
        ),
      ),
    );
  }

  //刷新时调用
      Future _refreshData(){

    final Completer completer = new Completer();
    currentpage = 1;
    feach(currentpage, pageSize).then((list) {
      setState(() {
          datas = list;
      });
    }).catchError((error) {
      print(error);
    });
    completer.complete(null);
    eturn completer.future;
  }

  //加载更多时调用
  Future _loadMoreData(){

    final Completer completer = new Completer();


    feach(currentpage, pageSize).then((list) {
      setState(() {
          datas.addAll(list);
      });
    }).catchError((error) {
      print(error);
    });
    completer.complete(null);

    return completer.future;
  }

  Future> feach(int pageNum,int pageSize){
   return _getDate(pageNum, pageSize);
  }

  Future>  _getDate(int pageNum,int pageSize) async{
    List flModels;
    String url = Constant.baseUrl + '福利/$pageSize/$pageNum';
    print(url);
      Response response = await dio.get(url);
      if(response.statusCode== HttpStatus.OK){//响应成功
          flModels = (response.data)['results'] ;
          currentpage = currentpage+1;//加载成功后才可加载下一页
      }else{//出问题
      }
    print(flModels.map((model) {
      return new FLModle.fromJson(model);
    }).toList().length);

    return flModels.map((model) {
      return new FLModle.fromJson(model);
    }).toList();

  }
}

你可能感兴趣的:(Flutter网络请求,解析json数据,列表展示)