聊天双向加载列表

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 允许继续向上传递通知
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容