You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用ListView.builder实现分页功能

Flutter ListView滚动到底部分页加载(每页10条)实现方案

核心实现思路

  • 维护关键状态:当前页码、总数据列表、是否正在加载、是否已加载全部数据
  • 通过ScrollController监听ListView滚动位置,设置提前量触发加载(提升用户体验)
  • 触发加载前先校验状态,避免重复请求或无效请求
  • 加载完成后更新数据与状态,结束加载状态

完整代码实现

import 'package:flutter/material.dart';

class PaginationListView extends StatefulWidget {
  const PaginationListView({super.key});

  @override
  State<PaginationListView> createState() => _PaginationListViewState();
}

class _PaginationListViewState extends State<PaginationListView> {
  final ScrollController _scrollController = ScrollController();
  List<String> _dataList = [];
  int _currentPage = 1;
  final int _pageSize = 10;
  bool _isLoading = false;
  bool _hasMore = true;

  @override
  void initState() {
    super.initState();
    _loadData();
    _scrollController.addListener(_onScroll);
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  void _onScroll() {
    // 距离底部200px时触发加载请求
    if (_scrollController.position.pixels >=
            _scrollController.position.maxScrollExtent - 200 &&
        !_isLoading &&
        _hasMore) {
      _loadData();
    }
  }

  // 模拟接口请求,实际项目替换为真实网络请求
  Future<void> _loadData() async {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
    });

    await Future.delayed(const Duration(seconds: 1));

    List<String> newData = List.generate(_pageSize, (index) {
      return "第${_currentPage}页 - 第${index + 1}条数据";
    });

    setState(() {
      _dataList.addAll(newData);
      _currentPage++;
      _isLoading = false;
      // 模拟加载5页后无更多数据
      if (_currentPage > 5) {
        _hasMore = false;
      }
    });
  }

  Widget _buildLoadMoreFooter() {
    if (!_hasMore) {
      return const Padding(
        padding: EdgeInsets.symmetric(vertical: 16),
        child: Center(child: Text('已加载全部数据')),
      );
    }
    return _isLoading
        ? const Padding(
            padding: EdgeInsets.symmetric(vertical: 16),
            child: Center(child: CircularProgressIndicator()),
          )
        : const SizedBox.shrink();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('分页加载示例')),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: _dataList.length + 1, // +1 对应加载更多的footer
        itemBuilder: (context, index) {
          if (index == _dataList.length) {
            return _buildLoadMoreFooter();
          }
          return ListTile(
            title: Text(_dataList[index]),
          );
        },
      ),
    );
  }
}

关键细节说明

  1. 滚动监听逻辑:设置200px的提前触发距离,避免用户滚动到底部才开始加载的等待感
  2. 状态校验:_isLoading防止同一时间重复发起请求,_hasMore避免无数据时继续请求
  3. 列表构建:itemCount包含数据量+footer,最后一个位置显示加载状态或无数据提示
  4. 请求兼容:示例用延迟模拟接口,实际项目中需替换为真实网络请求,并添加异常处理逻辑

实现效果示例

Flutter分页加载示例效果

内容的提问来源于stack exchange,提问作者shirisha siri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 13:15:29