Flutter ListView 上拉加载更多下拉刷新功能实现方法

网友投稿 484 2023-01-01


Flutter ListView 上拉加载更多下拉刷新功能实现方法

先上图

下拉刷新

跟原生开发一样,下拉刷新在flutter里提供的有组件实现 RefreshIndicator

一直不明白为啥组件中都提供下拉刷新,但就是没有上拉加载!!

我这请求接口数据用的是 http 库,是个第三方的是需要安装的 https://pub.dev/packages/http

用法如下

class MyHomePage extends StatefulWidget {

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

@override

MyHomeWidget2 createState() => MyHomeWidget2();

}

class MyHomeWidget2 extends State {

int page = 1;

List data = new List();

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

@override

void initState() {

super.initState();

this._onRefresh();

}

_fetchData() async {

var response = await http.get(

'${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');

var json = await convert.jsonDecode(response.body);

return json['data'];

}

Future _onRefresh() {

data.clear();

this.page = 1;

return _fetchData().then((data) {

setState(() => this.data.addAll(data));

});

}

@override

Widget build(BuildContext context) {

return Scaffold(

body: RefreshIndicator( // 在ListView外包一层 RefreshIndicator 组件

onRefresh: _onRefresh, // 添加onRefresh方法

child: 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 " +

new DateTime.now().toString()), // 为了看每次数据变动,这里直接取当前时间

trailing: Icon(Icons.chevron_right));

},

separatorBuilder: (context, index) {

return Divider();

},

)

));

}

}

链接文原: https://tomoya92.github.io/2019/07/17/flutter-refresh-loadmore/

上拉加载

上拉加载原理还是一样的,给ListView加一个 ScrollController 组件,然后通过事件监听滚动条的高度来显示和隐藏加载更多的组件

先将加载更多的组件写好

Widget _loadMoreWidget() {

return new Padding(

padding: const EdgeInsets.all(15.0), // 外边距

child: new Center(

child: new CircularProgressIndicator()

),

);

}

初始化一个 ScrollController 组件,将其设置给 ListView 组件的 controller 属性上

ScrollController _scrollController = new ScrollController();

child: ListView.separated(

controller: _scrollController,

//...

)

然后通过重写 dispost() 方法来处理加载更多组件的释放

@override

void dispose() {

_scrollController.dispose();

super.dispose();

}

最后通过数据源来控制界面渲染哪个组件,当数据源循环渲染的 index 跟数据源一样长时(其实少1,下标从0开始的)就渲染加载更多组件,让其显示出来,同时调用加载更多方法,获取数据,再通过state实现组件ui的更新

完整代码如下

class MyHomePage extends StatefulWidget {

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

@override

MyHomeWidget2 createState() => MyHomeWidget2();

}

class MyHomeWidget2 extends State {

int page = 1;

bool isLoadmore = false;

List data = new List();

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

ScrollController _scrollController = new ScrollController();

@override

void initState() {

super.initState();

this._onRefresh();

_scrollController.addListener(() {

if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {

_onLoadmore();

}

});

}

_fetchData() async {

var response = await http.get(

'${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');

var json = await convert.jsonDecode(response.body);

return json['data'];

}

Future _onRefresh() {

data.clear();

this.page = 1;

return _fetchData().then((data) {

setState(() => this.data.addAll(data));

});

}

Future _onLoadmore() {

this.page++;

return _fetchData().then((data) {

setState((){

this.data.addAll(data);

isLoadmore = false;

});

});

}

@override

void dispose() {

_scrollController.dispose();

super.dispose();

}

Widget _loadMoreWidget() {

returnhttp:// new Padding(

padding: const EdgeInsets.all(15.0),

child: new Center(

child: new CircularProgressIndicator()

),

);

}

@override

Widget build(BuildContext context) {

return Scaffold(

body: RefreshIndicator(

onRefresh: _onRefresh,

child: ListView.separated(

controller: _scrollController,

itemCount: this.data.length,

itemBuilder: (context, index) {

if (index == data.length - 1) {

return _loadMoreWidgIsPtEcWmUket();

} else {

var _data = this.data[index];

return ListTile(

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

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

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

" created at " +

new DateTime.now().toString()),

trailing: Icon(Icons.chevron_right));

}

},

separatorBuilder: (context, index) {

return Divider();

},

)

));

}

}

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:软件系统接口设计方案规范(管理系统接口设计)
下一篇:Eclipse下基于Java的OpenCV开发环境配置教程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~