首页 > 其他分享 >flutter:使用listview之三:上拉加载更多(flutter 3.7.0)

flutter:使用listview之三:上拉加载更多(flutter 3.7.0)

时间:2023-02-10 15:14:36浏览次数:55  
标签:index return 3.7 上拉 context child new flutter

一,配置用到的第三方库

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  dio: ^4.0.6
  flutter_screenutil: ^5.6.1
  fluttertoast: ^8.1.3

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: [email protected]

二,代码:

1,ListOne.dart

class ListOne {
  String title;
  String author;
  int id;

  ListOne(this.title,this.author, this.id) {}

  ListOne.fromJson(Map<String, dynamic>json)
      :title=json["title"],
        author = json["author"],
        id = json["id"];
}

2,list.dart

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:demolistmore/model/ListOne.dart';
import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';


class ItemList extends StatefulWidget {
  @override
  _MyList  createState()=> _MyList();
}

//封装的动态页面类
class _MyList extends State<ItemList>{

  ScrollController _scrollController = ScrollController(); //listview 的控制器
  //存放数据
  List<ListOne> _listData=[];
  //当前第几页
  int _currentPage = 0;
  int _total = 1;

  //上拉加载更多的提示文本
  String loadMoreText = "正在加载中...";
  //上拉加载更多的样式
  TextStyle loadMoreTextStyle = new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);

  //http方式获取数据
  Future<Null> getHttp() async{
    String url = 'http://api.lhdtest.com/item/list?page='+_currentPage.toString();
    print(url);
    try {
      var response = await Dio().get(url);
      //处理json到类中
      var resoMap=json.decode(response.toString());
      _total = resoMap['data']['total'];
      for (int i = 0; i < (resoMap['data']['list'].length); i++) {
        var itemOne = resoMap['data']['list'][i];
        ListOne goodsOne = new ListOne(itemOne['title'],itemOne['author'], itemOne['id']);
        _listData.add(goodsOne);
      }
      setState(() {
      });
    } catch (e) {
      print(e);
    }
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getHttp();
    _scrollController.addListener(() {
      print("_scrollController.addListener");
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        print("开始加载数据:_currentPage:"+_currentPage.toString());
        print("开始加载数据:_total:"+_total.toString());
        //已经滑到底了
        if (_currentPage < _total) {
          //还有数据,加载下一页
          setState(() {
            loadMoreText = "正在加载中...";
            loadMoreTextStyle = new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);
          });
          _loadMore();
        } else {
          setState(() {
            loadMoreText = "没有更多数据";
            loadMoreTextStyle = new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
          });
        }
      }
    });
  }

  //构造list的item
  Widget _buildRow(int index) {
      if (index == 5) {
          return _imageRow(index);
      } else {
          return _textRow(index);
      }
  }

  Widget _imageRow(int index) {
    String imageUrl = "https://images.taboola.com.cn/taboola/image/fetch/f_jpg%2Cq_auto%2Ch_350%2Cw_420%2Cc_fill%2Cg_faces:auto%2Ce_sharpen/http%3A//cdn.taboola.com/libtrc/static/thumbnails/7dc5d37f2949e30163c870e0e5585592.jpg";
    return Container(
      margin: EdgeInsets.all(0),
      color: Colors.white,
      child: Container(
        width:560.w,
        height:360.w,
        margin: EdgeInsets.fromLTRB(20.w, 20.w, 20.w, 0),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(30.w)),
          color: Colors.grey.withAlpha(40),
        ),
        child:Row(
            children:[
              Container(width:20.w),
              Image.network(imageUrl,height: 320.w,),
            ]
        ),

        alignment: Alignment.centerLeft,
      ),
    );
  }


  Widget _textRow(int index) {
    //非最后一行
    return Container(
      margin: EdgeInsets.all(0),
      color: Colors.white,
      child: Container(
        width:560.w,
        height:160.w,
        margin: EdgeInsets.fromLTRB(20.w, 20.w, 20.w, 0),
        //color: Colors.cyan,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(30.w)),
          color: Colors.grey.withAlpha(40),
        ),
        child:Row(
            children:[
              _titleWrapper(context, _listData[index].title),
              _authorWrapper(context, _listData[index].author),
            ]
        ),
      ),
    );
  }

  Widget _authorWrapper(BuildContext context, String text) {
    return Container(
      height: 160.w,
      width:150.w,
      margin: EdgeInsets.fromLTRB(0.w, 0, 0, 0),
      decoration: new BoxDecoration(
        //color: Colors.yellow,
      ),
      alignment: Alignment.centerLeft,
      child: Text(
        text,
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
        style: Theme.of(context).textTheme.headline6,
      ),
    );
  }

  Widget _titleWrapper(BuildContext context, String text) {
    return Container(
      height: 160.w,
      width:500.w,
      margin: EdgeInsets.fromLTRB(20.w, 0, 0, 0),
      decoration: new BoxDecoration(
        //color: Colors.red,
      ),
      alignment: Alignment.centerLeft,
      child: Text(
        text,
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
        style: Theme.of(context).textTheme.headline6,
      ),
    );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var content;
    if (_listData.length == 0) {
      content = new Center(
        // 可选参数 child:
        child: new CircularProgressIndicator(),
      );
    } else {
      content = _contentList();
    }

    //设置尺寸(填写设计中设备的屏幕尺寸)如果设计基于750dp * 1334dp的屏幕
    ScreenUtil.init(
        context,
        designSize: Size(750, 1334)
    );

    return Scaffold(
      appBar: AppBar(title: Text('小学三年级部编版'),),
      body: content,
    );
  }
  Widget _contentList() {
    return Stack(
      children: [
        new RefreshIndicator(
            onRefresh: _onRefresh,
            child: ListView.builder(
              itemCount: _listData.length+1,  //增加了一个上拉加载更多的指示
              itemBuilder: (BuildContext context, int index) {
                if (index == _listData.length) {
                  return _buildProgressMoreIndicator();
                } else {
                  return getItem(context,index);
                }
              },
              controller: _scrollController,
            )),
      ],
    );
  }
  //显示上拉加载更多的指示
  Widget _buildProgressMoreIndicator() {
    return new Padding(
      padding: const EdgeInsets.all(15.0),
      child: new Center(
        child: new Text(loadMoreText, style: loadMoreTextStyle),
      ),
    );
  }

  //上拉加载更多的方法
  Future<void> _loadMore() async {
    print('加载更多');

    if (_currentPage >= _total) {
      Fluttertoast.showToast(
          msg: "已经到达最后一页",
          toastLength: Toast.LENGTH_LONG,
          //toastLength: 60,
          gravity: ToastGravity.CENTER,
          timeInSecForIosWeb: 1,
          backgroundColor: Colors.blue,
          textColor: Colors.white,
          fontSize: 20.0
      );
    } else {
      if (_currentPage < 1) {
        _currentPage = 1;
      }
      _currentPage += 1;

      getHttp();
      await Future.delayed(Duration(milliseconds: 250), () {
        print('refresh');
      });
    }
  }

  //下拉刷新执行
  Future<void> _onRefresh() async {
    print('执行刷新');
    this._listData.clear();
    _currentPage = 1;
    getHttp();
    await Future.delayed(Duration(milliseconds: 500), () {
      print('refresh');
    });
  }

  Widget getItem(BuildContext context,int index) {
    return new GestureDetector(
      child:_buildRow(index),
    );
  }
}

3,接口返回的数据形式:

三,测试效果

四,查看flutter的版本:

liuhongdi@liuhongdideMBP ~ % flutter --version
Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b06b8b2710 (2 weeks ago) • 2023-01-23 16:55:55 -0800
Engine • revision b24591ed32
Tools • Dart 2.19.0 • DevTools 2.20.1

 

标签:index,return,3.7,上拉,context,child,new,flutter
From: https://www.cnblogs.com/architectforest/p/17108953.html

相关文章

  • Flutter使用SliverAppBar开发更多样式AppBar
    代码参考于【无聊的编码】FlutterSliver全家桶初体验,一起炫酷一下,有优化只是用官方的SliverAppBar只能做到如下样式:但是我们想要的结果是下面这样的:为此,我封装了一......
  • 3.7如何避免计算机计算出错
    计算机计算出错有两种避免该问题的方法:   首先是回避策略,即无视这些错误。根据程序目的的不同,有时一些微小的偏差并不会造成什么问题。一般来讲,在科学技术计算领域,......
  • Flutter中使用device_info获取设备信息
    1.安装插件配置 device_infodependencies:flutter:sdk:flutter#设备信息device_info:^1.0.0在pubspec.yaml中配置保存后,在VSCode环境中会自动下载依赖包。......
  • Flutter 中使用原生功能在IOS中的权限配置
    Flutter项目中在使用原生的一些功能时,必须要在Info.plist文件中配置使用权限,否则在提交审核时无法通过。1.添加权限打开配置权限的文件,路径为:ios▸Runner▸Info.plist 。......
  • Flutter中打包Android项目及升级Android项目
    1.打包Android项目1.用AndroidStudio打开Flutter项目中的android文件夹;2. 选择生成签名的APK;3.选择打包成APK,没有系统版本的限制;4.首次打包时,需要创建新的KeySt......
  • Flutter中修改Android项目的应用名称、应用图标、应用启动画面
    1.修改应用名称在android▸app▸src▸main▸AndroidManifest.xml中修改android:label="你的应用名称"。2.修改应用图标在android▸app▸src▸res▸mip......
  • Flutter 接入支付宝支付之前的准备工作
    1.选择应用类型打开支付宝开放平台,点击网页&移动应用。如果没有入驻成为开发者,请先注册。应用类型分为两大类:第三方应用、自用型应用。第三方应用:适用于服务商,为商户开发......
  • Flutter中使用connectivity实现网络检测
    1.安装插件配置 connectivity 插件。dependencies:flutter:sdk:flutterflutter_localizations:sdk:flutterdate_format:^1.0.6flutter_cupertino_dat......
  • 3.7 如何避免计算机计算出错
    计算机计算出错的原因之一是,采用浮点数来处理小数(另外,也有因“位溢出”而造成计算错误的情况)。作为程序的数据类型,不管是使用单精度浮点数还是双精度浮点数,都存在计算出......
  • flutter:适配屏幕(flutter_screenutil: ^5.6.1 / flutter 3.7.0 )
    一,flutter_screenutil库的地址:https://pub.dev/packages/flutter_screenutil代码地址:https://github.com/OpenFlutter/flutter_screenutil说明:刘宏缔的架构森......