Flutter快速加载更多列表插件loading_more_list_fast的使用
Flutter快速加载更多列表插件loading_more_list_fast的使用
loading_more_list_fast
是一个支持 ListView
, GridView
, WaterfallFlow
和 Slivers
的加载更多列表插件。它可以帮助开发者轻松实现具有加载更多功能的列表。
使用
添加依赖
在 pubspec.yaml
文件中添加依赖:
dependencies:
loading_more_list: any
然后在 Dart 文件中导入库:
import 'package:loading_more_list/loading_more_list_fast.dart';
准备数据集合
创建一个继承自 LoadingMoreBase<TuChongItem>
的类来管理数据:
class TuChongRepository extends LoadingMoreBase<TuChongItem> {
int pageindex = 1;
bool _hasMore = true;
bool forceRefresh = false;
@override
bool get hasMore => (_hasMore && length < 30) || forceRefresh;
@override
Future<bool> refresh([bool clearBeforeRequest = false]) async {
_hasMore = true;
pageindex = 1;
// 强制刷新列表时不清除列表
forceRefresh = !clearBeforeRequest;
var result = await super.refresh(clearBeforeRequest);
forceRefresh = false;
return result;
}
@override
Future<bool> loadData([bool isloadMoreAction = false]) async {
String url = "";
if (this.length == 0) {
url = "https://api.tuchong.com/feed-app";
} else {
int lastPostId = this[this.length - 1].postId;
url = "https://api.tuchong.com/feed-app?post_id=$lastPostId&page=$pageindex&type=loadmore";
}
bool isSuccess = false;
try {
// 为了清晰显示加载更多,在实际应用中可以移除这行代码
await Future.delayed(Duration(milliseconds: 500));
var result = await HttpClientHelper.get(url);
var source = TuChongSource.fromJson(json.decode(result.body));
if (pageindex == 1) {
this.clear();
}
for (var item in source.feedList) {
if (item.hasImage && !this.contains(item) && hasMore) this.add(item);
}
_hasMore = source.feedList.length != 0;
pageindex++;
isSuccess = true;
} catch (exception, stack) {
isSuccess = false;
print(exception);
print(stack);
}
return isSuccess;
}
}
参数
ListConfig
类定义了加载更多列表的主要参数:
参数名 | 描述 | 默认值 |
---|---|---|
itemBuilder |
列表项构建器 | 必填 |
sourceList |
数据源列表,必须扩展 LoadingMoreBase 类型 |
必填 |
showGlowLeading |
是否显示负滚动偏移方向的溢出光晕 | 0.0 |
showGlowTrailing |
是否显示正滚动偏移方向的溢出光晕 | - |
lastChildLayoutType |
最后一个子项的布局类型(加载更多/无更多项目) | LastChildLayoutType.foot |
extendedListDelegate |
WaterfallFlow 或 ExtendedList 的委托 |
- |
gridDelegate |
GridView 的委托 |
- |
indicatorBuilder |
不同加载状态的指示器构建器 | IndicatorWidget |
padding |
插入子级 Sliver 的空间量(仅适用于 SliverListConfig ) |
- |
childCountBuilder |
获取子项计数的构建器,输入为 sourceList.length |
- |
组件
LoadingMoreList
用于创建基本的加载更多列表:
LoadingMoreList(
ListConfig<TuChongItem>(
itemBuilder: ItemBuilder.itemBuilder,
sourceList: listSourceRepository,
padding: EdgeInsets.all(0.0),
),
)
GridView
通过 gridDelegate
参数定义 GridView
:
LoadingMoreList(
ListConfig<TuChongItem>(
itemBuilder: ItemBuilder.itemBuilder,
sourceList: listSourceRepository,
padding: EdgeInsets.all(0.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 3.0,
mainAxisSpacing: 3.0,
),
),
)
WaterfallFlow
通过 extendedListDelegate
参数定义 WaterfallFlow
:
LoadingMoreList(
ListConfig<TuChongItem>(
extendedListDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
itemBuilder: _buildItem,
sourceList: listSourceRepository,
padding: EdgeInsets.all(5.0),
),
)
Sliver/CustomScrollView
以下代码展示了如何在 CustomScrollView
中构建加载更多列表:
LoadingMoreCustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
title: Text("MultipleSliverDemo"),
),
/// SliverList
LoadingMoreSliverList(SliverListConfig<TuChongItem>(
itemBuilder: ItemBuilder.itemBuilder,
sourceList: listSourceRepository,
)),
SliverToBoxAdapter(
child: Container(
alignment: Alignment.center,
child: Text("Next list"),
color: Colors.blue,
height: 100.0,
),
),
/// SliverGrid
LoadingMoreSliverList(
SliverListConfig<TuChongItem>(
itemBuilder: ItemBuilder.itemBuilder,
sourceList: listSourceRepository1,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 3.0,
mainAxisSpacing: 3.0,
),
),
),
SliverPersistentHeader(
delegate: CommonExtentSliverPersistentHeaderDelegate(
Container(
alignment: Alignment.center,
child: Text("Pinned Content"),
color: Colors.red,
),
100.0),
pinned: true,
),
/// SliverWaterfallFlow
LoadingMoreSliverList(
SliverListConfig<TuChongItem>(
itemBuilder: buildWaterfallFlowItem,
sourceList: listSourceRepository2,
padding: EdgeInsets.symmetric(horizontal: 5.0),
extendedListDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
),
),
],
)
指示器状态
定义加载状态,使用 indicatorBuilder
参数:
enum IndicatorStatus {
None,
LoadingMoreBusying,
FullScreenBusying,
Error,
FullScreenError,
NoMoreLoad,
Empty
}
LoadingMoreList(
ListConfig<TuChongItem>(
itemBuilder: ItemBuilder.itemBuilder,
sourceList: listSourceRepository,
indicatorBuilder: _buildIndicator,
padding: EdgeInsets.all(0.0),
),
)
// 可以使用 IndicatorWidget 或自行构建 Widget
// 在此示例中,我们定义所有状态。
Widget _buildIndicator(BuildContext context, IndicatorStatus status) {
// 如果您的列表是 Sliver 列表,则应为其构建 Sliver 指示器
// isSliver = true,当在 Sliver 列表中使用时
bool isSliver = false;
Widget widget;
switch (status) {
case IndicatorStatus.None:
widget = Container(height: 0.0);
break;
case IndicatorStatus.LoadingMoreBusying:
widget = Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 5.0),
height: 15.0,
width: 15.0,
child: getIndicator(context),
),
Text("正在加载...不要着急")
],
);
widget = _setbackground(false, widget, 35.0);
break;
case IndicatorStatus.FullScreenBusying:
widget = Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 0.0),
height: 30.0,
width: 30.0,
child: getIndicator(context),
),
Text("正在加载...不要着急")
],
);
widget = _setbackground(true, widget, double.infinity);
if (isSliver) {
widget = SliverFillRemaining(
child: widget,
);
} else {
widget = CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: widget,
)
],
);
}
break;
case IndicatorStatus.Error:
widget = Text(
"好像出现了问题呢?",
);
widget = _setbackground(false, widget, 35.0);
widget = GestureDetector(
onTap: () {
listSourceRepository.errorRefresh();
},
child: widget,
);
break;
case IndicatorStatus.FullScreenError:
widget = Text(
"好像出现了问题呢?",
);
widget = _setbackground(true, widget, double.infinity);
widget = GestureDetector(
onTap: () {
listSourceRepository.errorRefresh();
},
child: widget,
);
if (isSliver) {
widget = SliverFillRemaining(
child: widget,
);
} else {
widget = CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: widget,
)
],
);
}
break;
case IndicatorStatus.NoMoreLoad:
widget = Text("没有更多的了。。不要拖了");
widget = _setbackground(false, widget, 35.0);
break;
case IndicatorStatus.Empty:
widget = EmptyWidget(
"这里是空气!",
);
widget = _setbackground(true, widget, double.infinity);
if (isSliver) {
widget = SliverToBoxAdapter(
child: widget,
);
} else {
widget = CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: widget,
)
],
);
}
break;
}
return widget;
}
收集垃圾
跟踪将要收集的索引,可以在那一刻收集垃圾(例如图像缓存):
LoadingMoreList(
ListConfig<TuChongItem>(
extendedListDelegate: ExtendedListDelegate(
collectGarbage: (List<int> indexes) {
/// 收集垃圾
},
),
),
)
视口构建器
跟踪进入视口的索引,这不包括缓存范围:
LoadingMoreList(
ListConfig<TuChongItem>(
extendedListDelegate: ExtendedListDelegate(
viewportBuilder: (int firstIndex, int lastIndex) {
print('viewport : [$firstIndex,$lastIndex]');
},
),
),
)
最后子项布局类型
在最后一个子项为加载更多/无更多项目的情况下,构建最后一个子项作为特殊子项:
enum LastChildLayoutType {
/// 作为默认子项
none,
/// 跟随最大子项的尾部布局偏移,并使用完整的交叉轴扩展
/// 在 `[ExtendedGridView]` 和 `[WaterfallFlow]` 中,最后一个子项作为加载更多项目/无更多项目
/// 具有完整的交叉轴扩展
fullCrossAxisExtent,
/// 在尾部作为脚部并使用完整的交叉轴扩展
/// 当子项不满视口时显示无更多项目
/// 如果子项满视口,则与 `fullCrossAxisExtent` 相同
foot,
}
关闭到尾部
当 List
的 reverse
属性为 true
时,布局如下:
类似于聊天列表,新会话将插入到零索引处。但当项目不满视口时,这并不正确。
为了解决这个问题,您可以将 closeToTrailing
设置为 true
,布局如下:
支持 [ExtendedGridView]
, [ExtendedList]
, [WaterfallFlow]
。
并且即使 reverse
为 false
时,布局也会靠近尾部。
LoadingMoreList(
ListConfig<TuChongItem>(
extendedListDelegate: ExtendedListDelegate(
closeToTrailing: true
),
),
)
更多关于Flutter快速加载更多列表插件loading_more_list_fast的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter快速加载更多列表插件loading_more_list_fast的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
loading_more_list_fast
是一个用于 Flutter 的插件,可以帮助你快速实现加载更多列表的功能。它支持懒加载、下拉刷新、上拉加载更多等常用功能,并且性能优化较好。以下是使用 loading_more_list_fast
的基本步骤和示例代码。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 loading_more_list_fast
依赖:
dependencies:
flutter:
sdk: flutter
loading_more_list_fast: ^2.0.0
然后运行 flutter pub get
来安装依赖。
2. 基本使用
以下是一个简单的示例,展示如何使用 loading_more_list_fast
实现一个加载更多列表。
import 'package:flutter/material.dart';
import 'package:loading_more_list_fast/loading_more_list_fast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Loading More List Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoadingMoreListDemo(),
);
}
}
class LoadingMoreListDemo extends StatefulWidget {
[@override](/user/override)
_LoadingMoreListDemoState createState() => _LoadingMoreListDemoState();
}
class _LoadingMoreListDemoState extends State<LoadingMoreListDemo> {
// 模拟数据源
final List<int> _dataSource = List.generate(20, (index) => index);
// 加载更多数据
Future<bool> _loadMore() async {
await Future.delayed(Duration(seconds: 2)); // 模拟网络请求延迟
setState(() {
_dataSource.addAll(List.generate(10, (index) => _dataSource.length + index));
});
return true;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Loading More List Demo'),
),
body: LoadingMoreList<int>(
itemBuilder: (BuildContext context, int item, int index) {
return ListTile(
title: Text('Item $item'),
);
},
sourceList: _dataSource,
loadMore: _loadMore,
hasMore: true, // 是否还有更多数据
onLoadMore: () async {
await _loadMore();
},
onRefresh: () async {
// 模拟刷新数据
await Future.delayed(Duration(seconds: 2));
setState(() {
_dataSource.clear();
_dataSource.addAll(List.generate(20, (index) => index));
});
return true;
},
),
);
}
}