Flutter分页加载数据插件flutter_stream_paging的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter分页加载数据插件flutter_stream_paging的使用

Flutter Stream Paging

Pub Package
style: effective dart MIT License


一个支持分页(无限加载)的Flutter包,适用于ListView和GridView。

Demo

ListView GridView
Example Project Example Project

DataSource

要创建PagingListViewPagingGridView,你需要创建一个继承自DataSource的类。

当你从DataSource继承时,需要覆盖两个方法:loadInitialloadPageAfter

这些函数的输出是一个包含两项的元组,其中第一项是一个列表。

例如:如果你的列表从页面索引为0开始。 -> 在加载初始数据时,输出应该是元组(Tuple2([…], 1)),其中1是加载更多项目时的下一页索引。

示例:

class ListViewDataSource extends DataSource<int, Note> {
  NoteRepository noteRepository;

  ListViewDataSource(this.noteRepository);

  [@override](/user/override)
  FutureOr<Tuple2<List<Note>, int>> loadInitial(int pageSize) async {
    // 加载第一页的数据
    return Tuple2(await noteRepository.getNotes(0), 1);
  }

  [@override](/user/override)
  FutureOr<Tuple2<List<Note>, int>> loadPageAfter(int params, int pageSize) async {
    // 如果当前页为4,则没有更多数据
    if (params == 4) {
      return Tuple2([], params + 1);
    } else {
      // 加载下一页的数据
      return Tuple2(await noteRepository.getNotes(params), params + 1);
    }
  }
}

Display on UI

要在UI上显示数据,目前可以使用PagingListViewPagingGridView

示例:

ListViewDataSource dataSource = ListViewDataSource(NoteRepository());

PagingListView<int, Note>.separated(
  key: key,
  builderDelegate: PagedChildBuilderDelegate<Note>(
    itemBuilder: (context, data, child) {
      // 构建每个Item
      return NoteWidget(data);
    },
  ),
  pageDataSource: dataSource,
  separatorBuilder: (_, index) => const SizedBox(height: 20,),
)

完整示例代码

import 'package:flutter/material.dart';

import 'package:flutter_stream_paging_example/home_page.dart';

void main() {
  runApp(const MyApp());
}

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(),
    );
  }
}

更多关于Flutter分页加载数据插件flutter_stream_paging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter分页加载数据插件flutter_stream_paging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,flutter_stream_paging 是一个用于 Flutter 的分页加载数据插件,它简化了从 API 获取分页数据的流程。以下是一个基本的代码案例,展示了如何使用 flutter_stream_paging 插件来实现分页加载数据。

首先,确保你已经将 flutter_stream_paging 添加到你的 pubspec.yaml 文件中:

dependencies:
  flutter:
    sdk: flutter
  flutter_stream_paging: ^最新版本号  # 请替换为实际最新版本号

然后运行 flutter pub get 来安装依赖。

示例代码

  1. 定义数据源

假设你有一个 API,它接受分页参数并返回分页数据。你需要一个数据源类来封装这些 API 调用。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_stream_paging/flutter_stream_paging.dart';
import 'package:http/http.dart' as http;

class ApiDataSource extends RemoteDataSource<int, Map<String, dynamic>> {
  ApiDataSource() : super(pageSize: 10); // 每页10个项目

  @override
  Future<DataResponse<Map<String, dynamic>>> fetchPage(int pageKey) async {
    try {
      final response = await http.get(
        Uri.parse('https://api.example.com/items'), // 替换为你的API URL
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer YOUR_API_TOKEN', // 如果需要身份验证
        },
        queryParameters: {'page': pageKey, 'perPage': pageSize},
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body) as Map<String, dynamic>;
        final items = data['items'] as List<Map<String, dynamic>>;
        return DataResponse.success(
          data: items,
          canLoadMore: items.length == pageSize, // 判断是否还有更多数据
        );
      } else {
        throw Exception('Failed to load data');
      }
    } catch (e) {
      return DataResponse.error(error: e.toString());
    }
  }
}
  1. 使用分页控制器和数据源

在你的 Flutter 应用中使用 PagingControllerApiDataSource 来获取分页数据。

import 'package:flutter/material.dart';
import 'package:flutter_stream_paging/flutter_stream_paging.dart';
import 'api_data_source.dart'; // 假设你把上面的代码保存在这个文件中

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flutter Stream Paging Demo')),
        body: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final PagingController<int, Map<String, dynamic>> _pagingController;

  @override
  void initState() {
    super.initState();
    final dataSource = ApiDataSource();
    _pagingController = PagingController(dataSource: dataSource);
  }

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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: PagingView<Map<String, dynamic>>(
        pagingController: _pagingController,
        builderDelegate: PagingBuilderDelegate<Map<String, dynamic>>(
          itemBuilder: (context, item, index) {
            return ListTile(
              title: Text(item['title'] as String), // 假设每个项目都有一个title字段
            );
          },
          errorIndicatorBuilder: (context, error) {
            return Center(child: Text('Error: $error'));
          },
          emptyIndicatorBuilder: (context) {
            return Center(child: Text('No more items'));
          },
          loadingIndicatorBuilder: (context) {
            return Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}

说明

  • ApiDataSource 继承自 RemoteDataSource 并实现了 fetchPage 方法,该方法负责从 API 获取数据。
  • PagingController 管理分页逻辑和数据。
  • PagingView 是一个 Flutter Widget,它使用 PagingControllerPagingBuilderDelegate 来显示分页数据。

这个示例展示了如何使用 flutter_stream_paging 插件来简化分页数据的加载和显示。你可以根据自己的需求进一步扩展和自定义这个示例。

回到顶部