如果你項目中有大量的列表刷新功能鸿摇,上拉加載更多需求傲茄,你可以嘗試這個方案隔心,只需要實例化一個NFTrefreshListController子類,實現(xiàn)對應(yīng)接口竟痰,就可以快速接入列表刷新需求签钩。
整個列表的需求相當于是獨立的掏呼,整體相當于已隔離,顆粒度相當滿意边臼。
依賴 easy_refresh, 你也可以替換其他刷新包哄尔。
示例代碼
class HomeTabSocial extends StatefulWidget {
const HomeTabSocial({Key? key}) : super(key: key);
@override
State<HomeTabSocial> createState() => _HomeTabSocialState();
}
class _HomeTabSocialState extends State<HomeTabSocial>
{
final socialController = HomeTabSocialController()..onLoad();
@override
Widget build(BuildContext context) {
return Scaffold(
body: NFTrefreshList(
controller: socialController,
itemBuilder: (context, index) => SocialFeedListTile(
item: socialController.data[index],
),
),
);
}
class HomeTabSocialController extends NFTrefreshListController<SocailFeedItem> {
@override
Future<List<SocailFeedItem>> fetchData(int page) async {
var result = await MyRequest.post('api/v1/newList', data: {
'member_id': '[memberId]',
'page': page,
'page_size': pageSize,
});
var data = result.data['data'] as Map;
var list = (data['list'] as List)
.map((e) => SocailFeedItem.from(e, data))
.toList();
return list;
}
@override
int get pageSize => 3;
@override
bool get hasFooter => true;
@override
bool get hasHeader => true;
}
源碼
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:get/get.dart';
class NFTrefreshList extends StatelessWidget {
final NFTrefreshListController controller;
final NullableIndexedWidgetBuilder itemBuilder;
final IndexedWidgetBuilder? separatorBuilder;
const NFTrefreshList({
Key? key,
required this.controller,
required this.itemBuilder,
this.separatorBuilder,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder<List>(
stream: controller.stream,
initialData: controller.data,
builder: (context, snap) {
if (snap.hasData) {
return EasyRefresh(
header: ClassicalHeader(),
footer: ClassicalFooter(),
controller: controller.easyRefresh,
onLoad: controller.onLoad,
onRefresh: controller.onRefresh,
child: ListView.separated(
itemCount: snap.data!.length,
itemBuilder: itemBuilder,
separatorBuilder:
separatorBuilder ?? (_, __) => const SizedBox.shrink(),
),
);
} else {
return const CupertinoActivityIndicator();
}
},
);
}
}
abstract class NFTrefreshListController<T> {
bool get hasHeader;
bool get hasFooter;
NFTrefreshListController();
final EasyRefreshController easyRefresh = EasyRefreshController();
final List<T> data = [];
int get pageSize;
int page = 1;
final _controller = StreamController<List>.broadcast();
Stream<List> get stream => _controller.stream;
Future<void> onLoad() async {
var list = await fetchData(page);
if (list.isNotEmpty) {
data.addAll(list);
page += 1;
_controller.add(data);
} else {
easyRefresh.finishLoad(success: true, noMore: true);
}
return;
}
Future<void> onRefresh() async {
easyRefresh.resetLoadState();
page = 1;
var list = await fetchData(page);
data.clear();
data.addAll(list);
page += 1;
_controller.add(data);
return;
}
Future<List<T>> fetchData(int page);
}