经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Flutter » 查看文章
Flutter ListView 上拉加载更多下拉刷新功能实现方法
来源:jb51  时间:2019/7/22 11:23:37  对本文有异议

先上图

下拉刷新

跟原生开发一样,下拉刷新在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<MyHomePage> {
 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<dynamic> _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<MyHomePage> {
 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<dynamic> _onRefresh() {
 data.clear();
 this.page = 1;
 return _fetchData().then((data) {
  setState(() => this.data.addAll(data));
 });
 }
 Future<dynamic> _onLoadmore() {
 this.page++;
 return _fetchData().then((data) {
  setState((){
  this.data.addAll(data);
  isLoadmore = false;
  });
 });
 }
 @override
 void dispose() {
 _scrollController.dispose();
 super.dispose();
 }
 Widget _loadMoreWidget() {
 return 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 _loadMoreWidget();
   } else {
    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();
   },
  )
 ));
 }
}

总结

以上所述是小编给大家介绍的Flutter ListView 上拉加载更多下拉刷新功能实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对w3xue网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

 友情链接: NPS