Flutter使用ListView加载列表数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010123643/article/details/83378949

移动端UI展示最常见的展示形式莫过于列表,Android中使用ListView/Recyclerview,iOS也有UIListView,都可以实现列表展示。Flutter作为兼容Android和iOS的移动UI框架,自然也有实现此功能的组件,即ListView。

本文数据采用爬虫爬取华尔街见闻全球资讯,然后采用GraphQL接口请求数据。显示效果如下
在这里插入图片描述

实现

  • 创建ListView 及每个显示的item
  • 网络请求
  • json解析
  • 数据显示

创建ListView及每个显示的item

使用如下代码创建一个ListView
其中listData 为列表加载的数据,因先初始化下 List listData = [];

      ListView getListView() => new ListView.builder(
      itemCount: (listData== null) ? 0 : listData.length,
      itemBuilder: (BuildContext context, int position) {
        return getItem(position);
      });

上面的getItem方法即为列表item的布局,使用Column与Row实现垂直和水平布局,核心代码如下:

new Padding(
            padding: new EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0),
            child: new Column(
              children: <Widget>[
                new Row(
                  crossAxisAlignment: CrossAxisAlignment.start, //纵向对齐方式:起始边对齐
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    new Expanded(
                      child: Container(
                        height: 95.0,
                        child: getImage(data.articleThumbnail),//封面
                        alignment: FractionalOffset.center,
                      ),
                      flex: 1,
                    ),
                    new Expanded(
                      child: Container(
                        height: 95.0,
                        margin: new EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
                        child: new Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Container(
                              child: new Text(
                                articleTitle,//标题
                                style: new TextStyle(
                                    fontSize: 20.0,
                                    fontWeight: FontWeight.w700),
                                maxLines: 1,
                                overflow: TextOverflow.ellipsis,
                              ),
                              alignment: FractionalOffset.topLeft,
                            ),
                            new Container(
                              child: new Text("${data.articleBrief}",//概要
                                  style: new TextStyle(fontSize: 16.0),
                                  maxLines: 2,
                                  overflow: TextOverflow.ellipsis),
                              alignment: Alignment.topLeft,
                            ),
                            new Expanded(
                              child: new Container(
                                margin:
                                    new EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0),
                                child: new Stack(
                                  children: <Widget>[
                                    new Container(
                                      child: new Text("${data.articleAuthor}",
                                          style: new TextStyle(fontSize: 10.0)),//作者
                                      alignment: FractionalOffset.bottomLeft,
                                    ),
                                    new Container(
                                      child: new Text(time_str,
                                          style: new TextStyle(fontSize: 10.0)),//时间
                                      alignment: FractionalOffset.bottomRight,
                                    ),
                                  ],
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                      flex: 3,
                    ),
                  ],
                ),
                new Divider(), //分割线
              ],
            ),
          )


  /**
   * 列表中图片加载
   */
  getImage(String img_url) {
    return new CachedNetworkImage(
      imageUrl: img_url,
      errorWidget: new Icon(Icons.error),
      fit: BoxFit.cover,
      height: 85.0,
      width: 100.0,
    );
  }

上述代码对应显示效果如下:
在这里插入图片描述
代码中CachedNetworkImage为网络图片缓存组件cached_network_image加载。

网络请求

网络请求使用的是开源的Dio,也可以直接使用http发送请求,

    Dio dio = new Dio();
    Response response = await dio.get(url);
    var jsonString = response.data;

json解析

json_serializable这个可以对json做很好的解析,类似于安卓的Gson,具体使用可以参考这篇文章,博主也是按文章进行操作的。

try {
      var news = new news_enity.fromJson(jsonString);
      var code = news.code;
      if (code == 0) {
        Result result = news.result;
        datas = result.data;
      }
    } catch (e) {
      print("异常==》" + e.toString());
    }

数据显示

使用 setState,将请求获得的数据datas传递给ListView的数据源listData

    setState(() {
      listData= datas;
    });

但列表显示肯定是要等到下网络请求到时间后才能显示的,所以有段时间我们需要用精度条转圈来显示等待,没有数据时,加载loading进度条,有数据后立马显示列表

  getBody() {
  if (listData.isEmpty) {
      return getProgressDialog();
    } else {
      return new Container(
        padding: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
        child: getListView(),
      );
    }
  }
  
  getProgressDialog() {
  // // CircularProgressIndicator是一个圆形的Loading进度条
    return new Center(child: new CircularProgressIndicator());
  }

最后效果如下图
在这里插入图片描述

项目源代码地址,此项目为持续开发项目,欢迎Start和Fork

扫描二维码关注公众号,回复: 3865262 查看本文章

猜你喜欢

转载自blog.csdn.net/u010123643/article/details/83378949