android listview显示静态数据库,Flutter ListView 用法,图文列表的实现,加载静态数据,请求接口渲染动态数据...

朋也的博客 » 首页 » 文章

Flutter ListView 用法,图文列表的实现,加载静态数据,请求接口渲染动态数据

作者:朋也

日期:2019-07-16

类别:flutter学习笔记

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

先上图

346ea3aca3ecb01f26b96e858f4cf80a.png

静态数据

首先创建项目,不多说

图文列表在 Flutter 里有个组件专门渲染图文列表的 ListTile 代码如下

import 'package:flutter/material.dart';

import 'dart:io';

import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

// This widget is the root of your application.

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Demo',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home: Scaffold(

appBar: AppBar(title: Text('Flutter Demo')), body: MyHomeWidget()));

}

}

class MyHomeWidget extends StatelessWidget {

@override

Widget build(BuildContext context) {

return ListView(

children: [

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题1'),

subtitle: Text('我是副标题1'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题2'),

subtitle: Text('我是副标题2'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题3'),

subtitle: Text('我是副标题3'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题4'),

subtitle: Text('我是副标题4'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题5'),

subtitle: Text('我是副标题5'),

trailing: Icon(Icons.chevron_right)),

],

);

}

}

渲染出来长下面这个样

2cc0b8239c911408cd8060ebce02d96f.png

可以看到它没有分割线,那怎么加上分割线呢?

添加分割线

使用 ListTile.divideTiles() 方法即可,如下

class MyHomeWidget extends StatelessWidget {

@override

Widget build(BuildContext context) {

return ListView(

children: ListTile.divideTiles(context: context, tiles: [

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题1'),

subtitle: Text('我是副标题1'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题2'),

subtitle: Text('我是副标题2'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题3'),

subtitle: Text('我是副标题3'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题4'),

subtitle: Text('我是副标题4'),

trailing: Icon(Icons.chevron_right)),

ListTile(

leading: Image.network(

"https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"),

title: Text('我是标题5'),

subtitle: Text('我是副标题5'),

trailing: Icon(Icons.chevron_right)),

]).toList(),

);

}

}

另一种添加分割线的方法,使用 ListView.separated() 方法,用法如下

class MyHomeWidget extends StatelessWidget {

List data = new List();

MyHomeWidget() {

for (var i = 0; i < 5; i++) {

data.add({

"title": "我是标题$i",

"subTitle": "我是副标题$i",

"imgUrl": "https://avatars3.githubusercontent.com/u/6915570?s=460&v=4"

});

}

}

@override

Widget build(BuildContext context) {

return ListView.separated(

itemCount: this.data.length,

itemBuilder: (context, index) {

var _data = this.data[index];

return ListTile(

leading: Image.network(_data["imgUrl"]),

title: Text(_data["title"]),

subtitle: Text(_data["subTitle"]),

trailing: Icon(Icons.chevron_right));

},

separatorBuilder: (context, index) {

return Divider();

},

);

}

}

效果图

62d4c16454059af739744e5aef22fe39.png

动态数据

上面第二种方法其实就算是一种动态数据了,不过开发app时列表中的数据一般都是通过请求接口来获取的

当涉及到请求接口,就是耗时操作,app的ui会事先渲染一个没有数据的界面,当接口请求的数据返回时,再通知 ListView 重新渲染,这时就要用到**有状态**的组件了

往上翻一下,可以看到,前面写的组件都是 无状态 的,也就是继承的组件都是 StatelessWidget

如何使用有状态的组件呢?其实使用 flutter create xxx初始化的项目里的那个计数器就是个有状态的组件,因为它涉及到了动态的数据了,既然默认初始化的组件就是有状态的组件,那直接拷贝过来用即可

class MyHomePage extends StatefulWidget {

MyHomePage({Key key}) : super(key: key);

@override

MyHomeWidget createState() => MyHomeWidget();

}

class MyHomeWidget extends State {

@override

Widget build(BuildContext context) {

return null;

}

}

可以看到自定义的类 MyHomePage 继承的是 StatefulWidget这个类,这个类里是个抽象类,里面有个抽象方法 createState() 要实现,写法很固定

下面又定义了一个类通过继承 State 类来实现业务逻辑,当语法接口的数据返回了,再调用父类的 setState() 方法,将数据源更新,组件就会自动的渲染了

这个 setState() 方法,如果会用 react.js 这样的前端框架,就很容易明白了,如果不明白,就把它当成 android 里的 listview.notifyDataSetChanged() 方法就可以了

这篇博客重点是记录 ListView 的用法,网络请求就不多说了,后面再介绍

我这用的接口是 https://cnodejs.org 的接口,因为要请求接口,并要将数据转成json, 这里要引入两个依赖,具体代码如下

import 'dart:io';

import 'dart:convert';

class MyHomeWidget extends State {

List data = new List();

var baseUrl = "https://cnodejs.org/api/v1";

MyHomeWidget() {

HttpClient client = new HttpClient();

client

.getUrl(Uri.parse("${this.baseUrl}/topics?mdrender=false"))

.then((HttpClientRequest request) {

// Optionally set up headers...

// Optionally write to the request object...

// Then call close.

return request.close();

}).then((HttpClientResponse response) async {

// Process the response.

// 通过 utf8 转码,jsonDecode 将数据转成json格式

var json = await response.transform(utf8.decoder).join();

setState(() {

data.addAll(jsonDecode(json)["data"]);

});

}).catchError((onError) {

print(onError.toString());

});

}

@override

Widget build(BuildContext context) {

return ListView.separated(

itemCount: this.data.length,

itemBuilder: (context, index) {

var _data = this.data[index];

return ListTile(

leading: Image.network(_data["author"]["avatar_url"]),

title: Text(_data["title"]),

subtitle: Text(_data["author"]["loginname"] +

" created at " +

_data["create_at"]),

trailing: Icon(Icons.chevron_right));

},

separatorBuilder: (context, index) {

return Divider();

},

);

}

}

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值