Flutter扩展列表插件extended_list的使用

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

Flutter扩展列表插件extended_list的使用

一、简介

extended_list 是一个增强版的Flutter列表组件库,它在标准的 ListViewGridView 基础上添加了更多功能,如追踪垃圾回收的子项、构建特殊的最后一个子项(例如加载更多/无更多项目)以及支持接近尾部布局等。该库可以帮助开发者更方便地处理复杂的列表逻辑,并且优化了性能。

pub package GitHub stars GitHub forks GitHub license GitHub issues

Web demo for ExtendedList

二、安装与导入

添加依赖

在你的 pubspec.yaml 文件中添加以下内容:

dependencies:
  extended_list: any

导入包

然后在需要使用的Dart文件中导入此库:

import 'package:extended_list/extended_list.dart';

三、主要特性

1. 收集垃圾 (CollectGarbage)

通过跟踪哪些索引被收集,可以在适当的时候清理缓存(例如图片缓存)。下面是一个简单的例子:

ExtendedListView.builder(
  extendedListDelegate: ExtendedListDelegate(
    collectGarbage: (List<int> garbages) {
      print("collect garbage : $garbages");
    },
  ),
  // 其他参数...
);

2. 视口构建器 (ViewportBuilder)

用于跟踪进入视口范围内的索引变化,但不包括缓存区域。这有助于监控当前可见的内容。

ExtendedListView.builder(
  extendedListDelegate: ExtendedListDelegate(
    viewportBuilder: (int firstIndex, int lastIndex) {
      print("viewport : [$firstIndex,$lastIndex]");
    },
  ),
  // 其他参数...
);

3. 最后一个子项布局类型构建器 (LastChildLayoutTypeBuilder)

允许根据条件自定义最后一个子项的布局方式,比如作为“加载更多”或“没有更多项目”的提示。

enum LastChildLayoutType {
  none,
  fullCrossAxisExtent,
  foot,
}

ExtendedListView.builder(
  itemCount: length + 1, // 假设有额外的一个占位符
  extendedListDelegate: ExtendedListDelegate(
    lastChildLayoutTypeBuilder: (index) => index == length
        ? LastChildLayoutType.foot
        : LastChildLayoutType.none,
  ),
  itemBuilder: (context, index) {
    if (index < length) {
      return ListTile(title: Text('Item $index'));
    } else {
      return Center(child: Text('No more items'));
    }
  },
);

4. 接近尾部布局 (CloseToTrailing)

当列表反转时,确保未填满整个视口时的新条目能够正确对齐到尾部,适用于聊天记录之类的场景。

ExtendedListView.builder(
  reverse: true,
  extendedListDelegate: ExtendedListDelegate(closeToTrailing: true),
  // 其他参数...
);

四、完整示例Demo

下面是一个完整的示例程序,演示了如何结合上述特性创建一个带有“加载更多”按钮的列表:

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> items = List.generate(20, (index) => "Item $index");

  void _loadMoreItems() {
    Future.delayed(Duration(seconds: 2), () {
      setState(() {
        items.addAll(List.generate(10, (index) => "Item ${items.length + index}"));
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ExtendedList Demo'),
      ),
      body: ExtendedListView.builder(
        itemCount: items.length + 1, // 加载更多的占位符
        extendedListDelegate: ExtendedListDelegate(
          lastChildLayoutTypeBuilder: (index) =>
              index == items.length ? LastChildLayoutType.foot : LastChildLayoutType.none,
        ),
        itemBuilder: (context, index) {
          if (index < items.length) {
            return ListTile(title: Text(items[index]));
          } else {
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: ElevatedButton(
                onPressed: _loadMoreItems,
                child: Text('Load More'),
              ),
            );
          }
        },
      ),
    );
  }
}

这个示例展示了如何使用 ExtendedListView.builder 来创建一个动态加载更多项目的列表。当用户滚动到底部时,会显示一个“加载更多”按钮,点击后将模拟网络请求并追加新的数据项。同时,它也利用了 lastChildLayoutTypeBuilder 来确保“加载更多”按钮总是出现在列表底部。


更多关于Flutter扩展列表插件extended_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter扩展列表插件extended_list的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,我可以为你提供一个关于如何在Flutter中使用extended_list插件的示例。extended_list是一个增强版的列表组件,它提供了一些额外的功能,比如加载更多数据时的下拉刷新和上拉加载等。

首先,你需要在你的pubspec.yaml文件中添加extended_list依赖:

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

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

接下来,我们可以编写一个简单的示例来演示如何使用extended_list

示例代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Extended List Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  // 模拟的数据列表
  List<String> items = List.generate(20, (i) => "Item ${i + 1}");
  bool hasMore = true;  // 是否还有更多数据

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Extended List Example"),
      ),
      body: ExtendedListView.builder(
        // 列表头部(可选)
        header: Container(
          height: 50,
          color: Colors.grey[200],
          alignment: Alignment.center,
          child: Text("List Header"),
        ),
        // 列表尾部(可选)
        footer: hasMore
            ? Container(
                height: 50,
                color: Colors.grey[200],
                alignment: Alignment.center,
                child: CircularProgressIndicator())
            : null,
        // 列表项构建器
        itemBuilder: (_, index) {
          if (index >= items.length && hasMore) {
            // 加载更多数据的占位符
            return Container(
              height: 50,
              alignment: Alignment.center,
              child: CircularProgressIndicator(),
            );
          } else if (index >= items.length) {
            // 没有更多数据时显示的占位符
            return Container(
              height: 50,
              alignment: Alignment.center,
              child: Text("No more data"),
            );
          } else {
            // 实际的列表项
            return ListTile(
              title: Text(items[index]),
            );
          }
        },
        // 列表项数量
        itemCount: items.length + (hasMore ? 1 : 0),  // 如果还有更多数据,则多加一个加载中的占位符
        // 加载更多数据的回调
        onLoadMore: () async {
          // 模拟网络请求延迟
          await Future.delayed(Duration(seconds: 2));

          // 加载更多数据
          setState(() {
            if (items.length < 50) {  // 假设最多加载到50条数据
              items.addAll(List.generate(20, (i) => "Item ${items.length + i + 1}"));
            } else {
              hasMore = false;  // 没有更多数据了
            }
          });
        },
        // 下拉刷新的回调
        onRefresh: () async {
          // 模拟网络请求延迟
          await Future.delayed(Duration(seconds: 1));

          // 刷新数据(这里简单重置数据)
          setState(() {
            items = List.generate(20, (i) => "Item ${i + 1}");
            hasMore = true;  // 重置后还有更多数据可以加载
          });

          // 结束刷新状态
          ExtendedListState.of(context)?.endRefresh();
        },
        // 启用下拉刷新
        enablePullDownRefresh: true,
      ),
    );
  }
}

解释

  1. 依赖添加:在pubspec.yaml文件中添加extended_list依赖。
  2. 构建UI:使用ExtendedListView.builder来构建列表。
  3. 头部和尾部:可选的头部和尾部组件,用于显示自定义内容。
  4. 列表项构建器itemBuilder用于构建列表项,包括加载更多数据的占位符和没有更多数据时的占位符。
  5. 加载更多数据onLoadMore回调用于加载更多数据,当列表滚动到底部时触发。
  6. 下拉刷新onRefresh回调用于处理下拉刷新操作,刷新数据后需要调用ExtendedListState.of(context)?.endRefresh()来结束刷新状态。
  7. 启用下拉刷新:通过enablePullDownRefresh属性启用下拉刷新功能。

希望这个示例能够帮助你理解如何在Flutter中使用extended_list插件。如果你有任何其他问题,请随时提问!

回到顶部