iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Flutter中怎么利用listview实现下拉刷新上拉加载更多功能
  • 302
分享到

Flutter中怎么利用listview实现下拉刷新上拉加载更多功能

2023-06-20 20:06:41 302人浏览 独家记忆
摘要

这期内容当中小编将会给大家带来有关Flutter中怎么利用listview实现下拉刷新上拉加载更多功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。下拉刷新在Flutter中系统已经为我们提供了Googl

这期内容当中小编将会给大家带来有关Flutter中怎么利用listview实现下拉刷新上拉加载更多功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。


下拉刷新

在Flutter中系统已经为我们提供了Google material design的刷新功能 , 样式与原生Android一样.

我们可以使用RefreshIndicator组件来实现Flutter中的下拉刷新,下面们还是先来看下如何使用吧

RefreshIndicator

构造方法:

 const RefreshIndicator({    Key key,    @required this.child,    this.displacement: 40.0,      //触发下拉刷新的距离    @required this.onRefresh,     //下拉回调方法    this.color,                   //进度指示器前景色 默认为系统主题色    this.backgroundColor,         //背景色    this.notificationPredicate: defaultScrollNotificationPredicate,  })

然后我们看一下效果以及实现方式:

Flutter中怎么利用listview实现下拉刷新上拉加载更多功能

然后我们看一下代码:

class _MyHomePageState extends State<MyHomePage> {  List list = new List(); //列表要展示的数据   @override  void initState() {    // TODO: implement initState    super.initState();    getData();  }    Future getData() async {    await Future.delayed(Duration(seconds: 2), () {      setState(() {        list = List.generate(15, (i) => '哈喽,我是原始数据 $i');      });    });  }  @override  Widget build(BuildContext context) {    return new Scaffold(      appBar: new AppBar(        // Here we take the value from the MyHomePage object that was created by        // the App.build method, and use it to set our appbar title.        title: new Text(widget.title),      ),      body: RefreshIndicator(        onRefresh: _onRefresh,        child: ListView.builder(          itemBuilder: _renderRow,          itemCount: list.length,        ),      ),    );  }  Widget _renderRow(BuildContext context, int index) {    return ListTile(      title: Text(list[index]),    );  }    Future<Null> _onRefresh() async {    await Future.delayed(Duration(seconds: 3), () {      print('refresh');      setState(() {        list = List.generate(20, (i) => '哈喽,我是新刷新的 $i');      });    });  }}

代码不复杂,我们一步步分析:

MyHomePage 只是返回一个State,这里省略了.

首先body里我们返回了一个RefreshIndicator,这个组件自带下拉回调,然后里面我们包裹了一个listview,

然后使用List.generate()方法来创建了一个长度为15的List,并把List里的值赋值给ListView Item中的ListTile。

下拉回调onRefresh 我们返回了一个改变list的方法 .

在上面的代码中我们使用_onRefresh()方法来处理下拉刷新的回调

  Future<Null> _onRefresh() async {    await Future.delayed(Duration(seconds: 3), () {      print('refresh');      setState(() {        list = List.generate(20, (i) => '哈喽,我是新刷新的 $i');      });    });  }

其中 Future.delayed()方法可以选择延迟处理任务,这里我们假设网络的延迟是3秒.

这样一个简单的下拉刷新就实现了.

上拉加载更多

对于加载更多的组件在Flutter中是没有提供的,所以在这里我们就需要考虑如何实现的。

在ListView中有一个ScrollController属性,它就是专门来控制ListView滑动事件,在这里我们可以根据ListView的位置来判断是否滑动到了底部来做加载更多的处理。

在这里我们可以使用如下代码来判断ListView 是否滑动到了底部

  @override  void initState() {    // TODO: implement initState    super.initState();    getData();    _scrollController.addListener(() {      if (_scrollController.position.pixels ==          _scrollController.position.maxScrollExtent) {        print('滑动到了最底部');        _getMore();      }    });  }

_scrollController是我们初始化的ScrollController对象,通过监听我们可以判断现在的位置是否是最大的下滑位置来判断是否下滑到了底部。

看一下代码和效果:

Flutter中怎么利用listview实现下拉刷新上拉加载更多功能

class _MyHomePageState extends State<MyHomePage> {  List list = new List(); //列表要展示的数据  ScrollController _scrollController = ScrollController(); //listview的控制器  int _page = 1; //加载的页数  bool isLoading = false; //是否正在加载数据  @override  void initState() {    // TODO: implement initState    super.initState();    getData();    _scrollController.addListener(() {      if (_scrollController.position.pixels ==          _scrollController.position.maxScrollExtent) {        print('滑动到了最底部');        _getMore();      }    });  }    Future getData() async {    await Future.delayed(Duration(seconds: 2), () {      setState(() {        list = List.generate(15, (i) => '哈喽,我是原始数据 $i');      });    });  }  @override  Widget build(BuildContext context) {    return new Scaffold(      appBar: new AppBar(        // Here we take the value from the MyHomePage object that was created by        // the App.build method, and use it to set our appbar title.        title: new Text(widget.title),      ),      body: RefreshIndicator(        onRefresh: _onRefresh,        child: ListView.builder(          itemBuilder: _renderRow,          itemCount: list.length,          controller: _scrollController,        ),      ),      // This trailing comma makes auto-fORMatting nicer for build methods.    );  }  Widget _renderRow(BuildContext context, int index) {    return ListTile(      title: Text(list[index]),    );  }    Future<Null> _onRefresh() async {    await Future.delayed(Duration(seconds: 3), () {      print('refresh');      setState(() {        list = List.generate(20, (i) => '哈喽,我是新刷新的 $i');      });    });  }    Future _getMore() async {    if (!isLoading) {      setState(() {        isLoading = true;      });      await Future.delayed(Duration(seconds: 1), () {        print('加载更多');        setState(() {          list.addAll(List.generate(5, (i) => '第$_page次上拉来的数据'));          _page++;          isLoading = false;        });      });    }  }  @override  void dispose() {    // TODO: implement dispose    super.dispose();    _scrollController.dispose();  }}

滑动到底部的时候,我们执行加载更多的方法,给list数据多加5条,这次我们把延迟改到了1秒:

  Future _getMore() async {    if (!isLoading) {      setState(() {        isLoading = true;      });      await Future.delayed(Duration(seconds: 1), () {        print('加载更多');        setState(() {          list.addAll(List.generate(5, (i) => '第$_page次上拉来的数据'));          _page++;          isLoading = false;        });      });    }  }

是的,看着上面的效果我们已经实现了下拉加载更多,但是因为我们是滑动到底部触发的,如果在正在请求的过程中多次下拉就会造成多次加载更多的情况,所以我们还得对这个做下处理为了避免多次触发,我们加了一个isLoading,在上拉方法执行的过程中不会再次执行.

可以看到,我们仅仅在上面代码的基础上加上了一个isLoading的变量,当这个变量的值为true时,就不会触发加载更多的操作。

而因为是网络请求,可能需要分页,所以我们加了个page参数来查看是第几次触发上拉加载.

因为我们加了个监听,在组件卸载掉的时候记得移除这个监听,所以:

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

这个一定不要忘记,养成好习惯,每次加了监听都跑到这个方法里移除掉.

这样,我们一个简单的上拉加载更多的功能就实现了.

但是还有个问题,没有用户交互啊,加载的时候要有个提示,于是我们尝试上拉的时候展示一个加载中的组件给用户:

首先我们创建加载更多时显示的Vidget

  Widget _getMoreWidget() {    return Center(      child: Padding(        padding: EdgeInsets.all(10.0),        child: Row(          mainAxisAlignment: MainAxisAlignment.center,          crossAxisAlignment: CrossAxisAlignment.center,          children: <Widget>[            Text(              '加载中...     ',              style: TextStyle(fontSize: 16.0),            ),            CircularProgressIndicator(strokeWidth: 1.0,)          ],        ),      ),    );  }

然后我们在listview的itemcount那里把count+1,相当于我们给listview加了个尾部的组件.

 body: RefreshIndicator(        onRefresh: _onRefresh,        child: ListView.builder(          itemBuilder: _renderRow,          itemCount: list.length + 1,   //这里!这里!这里!          controller: _scrollController,        ),

看一下效果是否满意:

Flutter中怎么利用listview实现下拉刷新上拉加载更多功能

嗯,基本符合要求,感觉那个刷新图标加的有点丑,画蛇添足了,不过功能都是ok了的.

当然, 大家可以根据自己的需要去自己实现想要的样式

看一下全部的代码:

 class MyHomePage extends StatefulWidget {  MyHomePage({Key key, this.title}) : super(key: key);  final String title;  @override  _MyHomePageState createState() => new _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> {  List list = new List(); //列表要展示的数据  ScrollController _scrollController = ScrollController(); //listview的控制器  int _page = 1; //加载的页数  bool isLoading = false; //是否正在加载数据  @override  void initState() {    // TODO: implement initState    super.initState();    getData();    _scrollController.addListener(() {      if (_scrollController.position.pixels ==          _scrollController.position.maxScrollExtent) {        print('滑动到了最底部');        _getMore();      }    });  }    Future getData() async {    await Future.delayed(Duration(seconds: 2), () {      setState(() {        list = List.generate(15, (i) => '哈喽,我是原始数据 $i');      });    });  }  @override  Widget build(BuildContext context) {    return new Scaffold(      appBar: new AppBar(        // Here we take the value from the MyHomePage object that was created by        // the App.build method, and use it to set our appbar title.        title: new Text(widget.title),      ),      body: RefreshIndicator(        onRefresh: _onRefresh,        child: ListView.builder(          itemBuilder: _renderRow,          itemCount: list.length + 1,          controller: _scrollController,        ),      ),      // This trailing comma makes auto-formatting nicer for build methods.    );  }  Widget _renderRow(BuildContext context, int index) {    if (index < list.length) {      return ListTile(        title: Text(list[index]),      );    }    return _getMoreWidget();  }    Future<Null> _onRefresh() async {    await Future.delayed(Duration(seconds: 3), () {      print('refresh');      setState(() {        list = List.generate(20, (i) => '哈喽,我是新刷新的 $i');      });    });  }    Future _getMore() async {    if (!isLoading) {      setState(() {        isLoading = true;      });      await Future.delayed(Duration(seconds: 1), () {        print('加载更多');        setState(() {          list.addAll(List.generate(5, (i) => '第$_page次上拉来的数据'));          _page++;          isLoading = false;        });      });    }  }    Widget _getMoreWidget() {    return Center(      child: Padding(        padding: EdgeInsets.all(10.0),        child: Row(          mainAxisAlignment: MainAxisAlignment.center,          crossAxisAlignment: CrossAxisAlignment.center,          children: <Widget>[            Text(              '加载中...',              style: TextStyle(fontSize: 16.0),            ),            CircularProgressIndicator(              strokeWidth: 1.0,            )          ],        ),      ),    );  }  @override  void dispose() {    // TODO: implement dispose    super.dispose();    _scrollController.dispose();  }}

上述就是小编为大家分享的Flutter中怎么利用listview实现下拉刷新上拉加载更多功能了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网精选频道。

--结束END--

本文标题: Flutter中怎么利用listview实现下拉刷新上拉加载更多功能

本文链接: https://www.lsjlt.com/news/299779.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在 Golang 中替换正则表达式匹配的文本?
    在 go 中,可使用 regexp.replaceall 函数替换符合正则表达式的文本,该函数需要三个参数:待替换字符串、匹配模式和替换文本。例如,将字符串中 "fox" 替换为 "do...
    99+
    2024-05-14
    golang 正则表达式
  • 如何在 Golang 中测试随机数生成器的准确性?
    在 go 中测试随机数生成器准确性的步骤包括:生成大量随机数并计算每个范围内的出现次数,以确保均匀分布。针对指定均值和标准差计算每个范围内的出现次数,以确保正态分布。 如何在 Gola...
    99+
    2024-05-14
    golang 随机数
  • 面向对象设计原则在C++中的体现
    c++++ 体现了 oop 原则,包括:封装:使用类将数据和方法封装在对象中。继承:允许派生类从基类继承数据和行为。多态:允许对象的行为根据其类型而改变,通过虚函数实现。 面向对象设计...
    99+
    2024-05-14
    c++ 面向对象
  • c语言怎么区分小数和整数
    c 语言区分小数和整数的方法有:数据类型不同:小数类型(float、double)包含小数点,整数类型(int)不包含。printf() 函数中使用不同格式化字符串:小数用 %f,整数用...
    99+
    2024-05-14
    c语言
  • 设计模式在C++ 中的可复用性和可扩展性
    在 c++++ 中,设计模式通过提供经过验证的解决方案来提高可复用性和可扩展性。可复用性允许重复使用代码,例如 factory method 模式,它支持创建不同的产品而不影响具体类。可...
    99+
    2024-05-14
    c++ 设计模式 高可扩展性
  • C++语法中函数模板的灵活运用
    C++ 语法中函数模板的灵活运用 函数模板是 C++ 中的一项强大功能,允许您创建可用于不同数据类型的一组代码。这可以提高代码的可重用性,并使您能够编写更通用、更可维护的代码。 语法 ...
    99+
    2024-05-14
    c++语法 函数模板 c++
  • c语言怎么计算字符串长度和宽度
    在 c 语言中,计算字符串长度和宽度的函数分别为:strlen() 函数用于计算字符串长度,不包括终止符 '\0'。strwidth() 函数用于计算字符串在终端中的宽度,返回显示像素数...
    99+
    2024-05-14
    c语言
  • 如何用 Golang 正则匹配多个单词或字符串?
    golang 正则表达式使用管道符 | 来匹配多个单词或字符串,将各个选项作为逻辑 or 表达式分隔开来。例如:匹配 "fox" 或 "dog":fox|dog匹配 "quick"、"b...
    99+
    2024-05-14
    golang 正则 python
  • c语言怎么跳出多层循环
    在 c 语言中,可以使用嵌套的 break 语句跳出多层循环。对于每个要跳出的循环层,都需要一个单独的 break 语句。例如:使用一个 break 语句跳出内层循环再使用一个 brea...
    99+
    2024-05-14
    c语言
  • c语言怎么注释成中文
    c语言中文注释提供两种方式:行内注释(以"//"开头)和块注释(以"/"开头并以"/"结尾)。最佳实践包括:使用简明扼要的语言,在函数和类开头处添加块注释,在关键部分添加行内注释,保持注...
    99+
    2024-05-14
    c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作