import 'package:flutter/material.dart';
class BidirectionalListPage extends StatefulWidget {
const BidirectionalListPage({super.key});
@override
State<BidirectionalListPage> createState() => _BidirectionalListPageState();
}
class _BidirectionalListPageState extends State<BidirectionalListPage> {
final ScrollController _controller = ScrollController();
final List<int> _items = List.generate(20, (i) => i); // 初始数据
bool _isLoadingUp = false;
bool _isLoadingDown = false;
@override
void initState() {
super.initState();
_controller.addListener(_onScroll);
}
void _onScroll() {
const threshold = 100.0; // 离边界多少像素触发
// 向上加载(历史数据)
if (_controller.position.pixels <=
_controller.position.minScrollExtent + threshold) {
_loadMoreUp();
}
// 向下加载(未来数据)
if (_controller.position.pixels >=
_controller.position.maxScrollExtent - threshold) {
_loadMoreDown();
}
}
Future<void> _loadMoreUp() async {
if (_isLoadingUp) return; // 已经在加载,避免重复触发
setState(() => _isLoadingUp = true);
await Future.delayed(const Duration(seconds: 1)); // 模拟网络请求
final first = _items.first;
final newItems = List.generate(10, (i) => first - (i + 1));
setState(() {
_items.insertAll(0, newItems.reversed.toList());
_isLoadingUp = false;
});
// 保持加载后视图位置不跳动
_controller.jumpTo(_controller.offset + 60 * newItems.length);
}
Future<void> _loadMoreDown() async {
if (_isLoadingDown) return;
setState(() => _isLoadingDown = true);
await Future.delayed(const Duration(seconds: 1));
final last = _items.last;
final newItems = List.generate(10, (i) => last + (i + 1));
setState(() {
_items.addAll(newItems);
_isLoadingDown = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("双向加载 ListView")),
body: ListView.builder(
controller: _controller,
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: Center(child: Text("Index: ${_items[index]}")),
);
},
),
);
}
}
NotificationListener:onNotification()
bool notificationChange(Notification notification) {
if (notification is UserScrollNotification) {
if (notification.direction == ScrollDirection.forward) {
// 用户手指向下滑动(内容往上滚)
debugPrint('👆 用户向下滑动了');
userScrolledUp = true;
} else if (notification.direction == ScrollDirection.reverse) {
// 用户手指向上滑动(内容往下滚)
debugPrint('👇 用户向上滑动了');
// logic.userScrolledUp = false;
} else if (notification.direction == ScrollDirection.idle) {
debugPrint('👇 用户滑动结束了');
// 顶部触发
if (scrollController.position.pixels <=
scrollController.position.minScrollExtent + threshold) {
Logger.safePrint('====》开始拉取');
loadMoreUp();
}
// 底部触发
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent - threshold) {
loadMoreDown();
}
}
}
return false; // 返回 false 允许继续向上传递通知
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。