搜索插件、代码仓与 APP 分类

very_good_infinite_list 封面
插件详情v0.9.0

very_good_infinite_list

一个用于轻松显示分页数据的库,由 Very Good Ventures 创建。非常适合活动动态、新闻动态等场景。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
1.5万
喜欢数
309
Pub 分数
150

安装插件

flutter pub add very_good_infinite_list

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

由 Very Good Ventures 开发的 Flutter 包,可简化分页列表的实现,非常适合新闻动态或活动流等无限滚动界面。它能处理加载状态、错误恢复以及自动触发分页,且代码量极少。该包注重性能和开发者体验,可无缝集成到需要懒加载数据的应用中。

适合场景

  • 无限滚动信息流
  • 新闻和博客列表
  • 活动时间线
  • 用户生成内容流
  • 电子商务产品网格

主要特点

  • 自动分页处理
  • 内置的加载和错误状态
  • 简单的 API,设置最少
  • 支持下拉刷新
  • 针对性能进行了优化

适合对象

  • 开发基于信息流的应用程序的开发者
  • 注重快速UI开发的团队
  • 需要流畅无限滚动的项目
  • 大型数据集的应用程序
  • Flutter 初学者寻求可靠的分页功能

使用建议

  • 需要一个支持分页获取数据的数据源
  • 对复杂滚动行为的自定义有限
  • 不适用于非列表可滚动控件
  • 依赖外部状态管理
  • 可能需要额外的逻辑来过滤或排序

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

Very Good Infinite List

Very Good Ventures Very Good Ventures

Developed with 💙 by Very Good Ventures 🦄

ci coverage pub package License: MIT style: very good analysis

[!NOTE] There is an active proposal to integrate this package's functionality directly into the Flutter framework. Follow the conversation and share your feedback in flutter/flutter#177451.


A library for easily displaying paginated data, created by Very Good Ventures.

InfiniteList comes in handy when building features like activity feeds, news feeds, or anywhere else where you need to lazily fetch and render content for users to consume.

Example

Usage

The InfiniteList API is very similar to that of ListView.builder. A basic implementation requires four parameters:

  • An itemCount that represents the amount of items that should be rendered using the itemBuilder.
  • An itemBuilder that is responsible for returning a widget for every index of the itemCount.
  • A hasReachedMax flag that indicates if any more data is available.
  • An onFetchData callback that's triggered whenever new data should be fetched.

Example

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var _items = <String>[];
  var _isLoading = false;

  void _fetchData() async {
    setState(() {
      _isLoading = true;
    });

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

    if (!mounted) {
      return;
    }

    setState(() {
      _isLoading = false;
      _items = List.generate(_items.length + 10, (i) => 'Item $i');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Simple Example'),
      ),
      body: InfiniteList(
        itemCount: _items.length,
        isLoading: _isLoading,
        onFetchData: _fetchData,
        separatorBuilder: (context, index) => const Divider(),
        itemBuilder: (context, index) {
          return ListTile(
            dense: true,
            title: Text(_items[index]),
          );
        },
      ),
    );
  }
}
Customizations
InfiniteList

InfiniteList has multiple optional parameters which allow you to customize the loading and error behavior.

InfiniteList<String>(
  itemCount: 3,
  hasReachedMax: false,
  onFetchData: () => _fetchData(),
  itemBuilder: (context, index) => ListTile(title: Text('$index')),

  // An optional [ScrollController] this [InfiniteList] will attach to.
  // It's used to detect when the list has scrolled to the appropriate position
  // to call [onFetchData].
  //
  // Is optional and mostly used only for testing. If set to `null`, an
  // internal [ScrollController] is used instead.
  scrollController: _scrollController,

  // Indicates if new items are currently being loaded.
  //
  // While set to `true`, the [onFetchData] callback will not be triggered
  // and the [loadingBuilder] will be rendered.
  //
  // Is set to `false` by default.
  isLoading: false,

  // Indicates if an error has occurred.
  //
  // While set to `true`, the [onFetchData] callback will not be triggered
  // and the [errorBuilder] will be rendered.
  //
  // Is set to `false` by default.
  hasError: false,

  // Indicates if the list should be reversed.
  //
  // If set to `true`, the list of items, [loadingBuilder] and [errorBuilder]
  // will be rendered from bottom to top.
  //
  // Is set to `false` by default.
  reverse: false,

  // Indicates if the extent of the ScrollView in the scrollDirection
  // should be determined by the contents being viewed.
  //
  // Is set to `false` by default.
  shrinkWrap: false,

  // The duration with which calls to [onFetchData] will be debounced.
  //
  // Is set to a duration of 100 milliseconds by default.
  debounceDuration: const Duration(milliseconds: 100),

  // The offset, in pixels, that the internal [ScrollView] must be scrolled over
  // to trigger [onFetchData].
  // 
  // Defaults to the same as [RenderAbstractViewport.defaultCacheExtent], which is 250.
  cacheExtent: 250.0,

  // The amount of space by which to inset the list of items.
  //
  // Is optional and can be `null`.
  padding: const EdgeInsets.all(16.0),

  // An optional builder that's shown when the list of items is empty.
  //
  // If `null`, nothing is shown.
  emptyBuilder: (context) => const Center(child: Text('No items.')),
  
  // Flag used to center the empty builder, it is optional and defaults to false
  centerEmpty: true,

  // An optional builder that's shown at the end of the list when [isLoading]
  // is `true`.
  //
  // If `null`, a default builder is used that renders a centered
  // [CircularProgressIndicator].
  loadingBuilder: (context) => const Center(child: CircularProgressIndicator()),

  // Flag used to center the loading builder, it is optional and defaults to false
  centerLoading: true,

  // An optional builder that's shown when [hasError] is not `null`.
  //
  // If `null`, a default builder is used that renders the text `"Error"`.
  errorBuilder: (context) => const Center(child: Text('Error')),

  // Flag used to center the error builder, it is optional and defaults to false
  centerError: true,

  // An optional builder that, when provided, is used to show a widget in
  // between every pair of items.
  //
  // If the [itemBuilder] returns a [ListTile], this is commonly used to render
  // a [Divider] between every tile.
  //
  // Is optional and can be `null`.
  separatorBuilder: (context, index) => const Divider(),

  // An optional [Axis] to be used by the internal [ScrollView] that defines
  // the axis of scroll. 
  //
  // Is set to `Axis.vertical` by default.
  scrollDirection: Axis.vertical,

  // An optional [ScrollPhysics] to be used by the internal [ScrollView].
  //
  // Default to tha same as [ScrollView].
  physics: const AlwaysScrollableScrollPhysics(),
);

Refer to the example to see both basic and complex usage of InfiniteList.

所属分类

源码仓库

使用此插件的项目