Flutter无限滚动分页插件hookified_infinite_scroll_pagination的使用

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

Flutter无限滚动分页插件hookified_infinite_scroll_pagination的使用

hookified_infinite_scroll_paginationinfinite_scroll_pagination 包的 Hook 版本。此包允许你轻松实现无限滚动分页功能。

安装

在你的项目中添加依赖:

flutter pub add hookified_infinite_scroll_pagination

请注意,你不需要再单独安装 infinite_scroll_pagination,因为 hookified_infinite_scroll_pagination 已经重新导出了 infinite_scroll_pagination 中的所有内容。

基本用法

基于 EdsonBueno/infinite_scroll_pagination/example/example.md

import 'package:flutter/material.dart';
import 'package:hookified_infinite_scroll_pagination/hookified_infinite_scroll_pagination.dart';

class CharacterListView extends HookWidget {
  static const _pageSize = 20;

  @override
  Widget build(BuildContext context) {
    // 初始化 PagingController
    final _pagingController = usePagingController(
      firstPageKey: 0, // 第一页的 key
      onPageRequest: (pageKey, pagingController) async {
        try {
          // 获取新的数据列表
          final newItems = await RemoteApi.getCharacterList(pageKey, _pageSize);
          final isLastPage = newItems.length < _pageSize;
          if (isLastPage) {
            // 如果这是最后一页,则调用 appendLastPage 方法
            pagingController.appendLastPage(newItems);
          } else {
            // 否则,计算下一页的 key 并调用 appendPage 方法
            final nextPageKey = pageKey + newItems.length;
            pagingController.appendPage(newItems, nextPageKey);
          }
        } catch (error) {
          // 处理错误
          pagingController.error = error;
        }
      }
    );

    // 使用 PagedListView 显示数据
    return PagedListView<int, CharacterSummary>(
      pagingController: _pagingController,
      builderDelegate: PagedChildBuilderDelegate<CharacterSummary>(
        itemBuilder: (context, item, index) => CharacterListItem(
          character: item,
        ),
      ),
    );
  }
}

在上述代码中,我们创建了一个名为 CharacterListView 的小部件,该小部件实现了无限滚动分页功能。以下是一些关键点:

  1. 初始化 PagingController

    final _pagingController = usePagingController(
      firstPageKey: 0,
      onPageRequest: (pageKey, pagingController) async {
        // 获取新数据的逻辑
      }
    );
    

    这里定义了 usePagingController 方法来初始化一个 PagingController,并设置了获取新数据的逻辑。

  2. 获取新数据

    final newItems = await RemoteApi.getCharacterList(pageKey, _pageSize);
    final isLastPage = newItems.length < _pageSize;
    

    这里通过调用 RemoteApi.getCharacterList 方法从服务器获取数据,并检查是否为最后一页。

  3. 处理数据

    if (isLastPage) {
      pagingController.appendLastPage(newItems);
    } else {
      final nextPageKey = pageKey + newItems.length;
      pagingController.appendPage(newItems, nextPageKey);
    }
    

    根据数据长度判断是否为最后一页,并相应地调用 appendLastPageappendPage 方法。

  4. 显示数据

    return PagedListView<int, CharacterSummary>(
      pagingController: _pagingController,
      builderDelegate: PagedChildBuilderDelegate<CharacterSummary>(
        itemBuilder: (context, item, index) => CharacterListItem(
          character: item,
        ),
      ),
    );
    

更多关于Flutter无限滚动分页插件hookified_infinite_scroll_pagination的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter无限滚动分页插件hookified_infinite_scroll_pagination的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个使用 hookified_infinite_scroll_pagination 插件在 Flutter 中实现无限滚动分页的示例代码。这个插件使得在 Flutter 中实现分页加载变得更加简洁和高效。

首先,确保在你的 pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  hookified_infinite_scroll_pagination: ^x.y.z  # 请替换为最新版本号

然后运行 flutter pub get 来获取依赖。

以下是一个完整的示例,展示如何使用 hookified_infinite_scroll_pagination 实现无限滚动分页:

import 'package:flutter/material.dart';
import 'package:hookified_infinite_scroll_pagination/hookified_infinite_scroll_pagination.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Infinite Scroll Pagination Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: InfiniteScrollPage(),
    );
  }
}

class InfiniteScrollPage extends HookWidget {
  const InfiniteScrollPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final paginationController = usePaginationController<int>();

    useEffect(() {
      // Fetch initial data
      fetchPage(paginationController, 1);
      
      // Listen for page changes
      return paginationController.pageStream.subscribe((pageKey) {
        fetchPage(paginationController, pageKey);
      });
    }, []);

    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Scroll Pagination Demo'),
      ),
      body: paginationController.pageViews.when(
        data: (pageViews) => LazyColumn(
          controller: paginationController.scrollController,
          children: pageViews,
        ),
        loading: () => Center(child: CircularProgressIndicator()),
        error: (error, _) => Center(child: Text('Error: $error')),
        empty: () => Center(child: Text('No more items')),
      ),
    );
  }

  Future<void> fetchPage(PaginationController<int> controller, int pageKey) async {
    try {
      // Simulate a network request with a delay
      await Future.delayed(Duration(seconds: 1));

      // Mock data fetch
      final items = List.generate(10, (index) => 'Item ${(pageKey - 1) * 10 + index + 1}');

      // Add items to the controller
      controller.appendLastPage(items);
    } catch (error) {
      // Handle errors
      controller.refreshLastError(error);
    }
  }
}

// Custom LazyColumn widget to handle lazy loading with PaginationController
@optimized
class LazyColumn extends StatelessWidget {
  final ScrollController controller;
  final List<Widget> children;

  const LazyColumn({
    required this.controller,
    required this.children,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollNotification>(
      onNotification: (scrollNotification) {
        if (scrollNotification is ScrollEndNotification &&
            scrollNotification.metrics.pixels ==
                scrollNotification.metrics.maxScrollExtent) {
          // Scroll to the bottom, you can add custom logic here
        }
        return true;
      },
      child: ListView.builder(
        controller: controller,
        itemCount: children.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(children[index].toString()),
          );
        },
      ),
    );
  }
}

解释

  1. 依赖引入:在 pubspec.yaml 文件中添加 hookified_infinite_scroll_pagination 依赖。
  2. 创建应用:在 MyApp 中定义 MaterialAppInfiniteScrollPage
  3. PaginationController:使用 usePaginationController 创建一个分页控制器。
  4. useEffect Hook:在 useEffect 中,初始化数据并监听分页变化。
  5. 页面视图:使用 paginationController.pageViews 渲染页面视图,支持加载中、错误、空状态。
  6. 数据获取:定义 fetchPage 方法模拟网络请求并添加数据到分页控制器。
  7. LazyColumn:自定义 LazyColumn 组件处理滚动通知,监听滚动到底部的事件(可以根据需求添加自定义逻辑)。

这个示例展示了如何使用 hookified_infinite_scroll_pagination 实现基本的无限滚动分页功能,你可以根据实际需求进行扩展和修改。

回到顶部