一,配置用到的第三方库
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