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

如何为Flutter ListView.builder添加分页功能(替代无限滚动)

实现分页替代ListView.builder无限滚动

要实现每页固定显示x条数据、手动切换分页的效果,核心是控制每次展示的数据切片,同时添加分页交互控件,具体实现如下:

核心思路

  1. 维护分页状态:当前页码、每页显示条数
  2. 根据当前页码计算要展示的数据范围,从总数据中截取对应切片
  3. 用ListView.builder展示当前页数据
  4. 添加分页切换按钮,处理边界判断(比如第一页禁用上一页,最后一页禁用下一页)

完整代码示例

class PaginatedListView extends StatefulWidget {
  final List<String> allData;
  final int itemsPerPage;

  const PaginatedListView({
    super.key,
    required this.allData,
    required this.itemsPerPage,
  });

  @override
  State<PaginatedListView> createState() => _PaginatedListViewState();
}

class _PaginatedListViewState extends State<PaginatedListView> {
  int currentPage = 1;

  // 获取当前页要展示的数据切片
  List<String> get currentPageData {
    final startIndex = (currentPage - 1) * widget.itemsPerPage;
    final endIndex = startIndex + widget.itemsPerPage;
    // 处理最后一页数据不足的情况
    return widget.allData.sublist(
      startIndex,
      endIndex > widget.allData.length ? widget.allData.length : endIndex,
    );
  }

  // 计算总页数
  int get totalPages {
    return (widget.allData.length / widget.itemsPerPage).ceil();
  }

  // 切换到上一页
  void goToPreviousPage() {
    if (currentPage > 1) {
      setState(() {
        currentPage--;
      });
    }
  }

  // 切换到下一页
  void goToNextPage() {
    if (currentPage < totalPages) {
      setState(() {
        currentPage++;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 分页列表区域
        Expanded(
          child: ListView.builder(
            itemCount: currentPageData.length,
            itemBuilder: (context, index) {
              return Card(
                child: ListTile(
                  title: Text(currentPageData[index]),
                ),
              );
            },
          ),
        ),
        // 分页控制栏
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 16),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: currentPage > 1 ? goToPreviousPage : null,
                child: const Text('上一页'),
              ),
              const SizedBox(width: 20),
              Text('第 $currentPage / $totalPages 页'),
              const SizedBox(width: 20),
              ElevatedButton(
                onPressed: currentPage < totalPages ? goToNextPage : null,
                child: const Text('下一页'),
              ),
            ],
          ),
        ),
      ],
    );
  }
}

使用方式

在需要的地方传入总数据列表和每页显示条数即可:

PaginatedListView(
  allData: yourFullDataList, // 你的完整数据列表
  itemsPerPage: 10, // 设置每页要显示的条数x
)

关键细节说明

  • currentPageData 通过计算起始/结束索引,从总数据中截取当前页内容,自动处理最后一页数据不足的情况
  • totalPages 用ceil()方法向上取整,确保总页数为整数
  • 分页按钮会根据当前页码状态自动禁用/启用,避免出现越界操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:10:50