Flutter懒加载粘性头部插件lazy_sticky_headers的使用

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

Flutter懒加载粘性头部插件lazy_sticky_headers的使用

lazy_sticky_headers

一个带有懒加载支持的粘性头部列表小部件的 Flutter 实现。相比其他非懒加载实现,它具有显著的性能提升。

特性

  • 头部和内容都是懒加载的。
  • 支持程序化滚动到列表中的特定项。

开始使用

在你的 Flutter 项目 pubspec.yaml 文件中添加以下依赖:

dependencies:
  ...
  lazy_sticky_headers:

在你的库中添加以下导入:

...
import 'package:lazy_sticky_headers/lazy_sticky_headers.dart';

使用示例

定义一个 LazyStickyHeaders 小部件

LazyStickyHeaders<String, String>(
  scrollPhysics: const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()),

  // 头部
  header: List.generate(5, (header) => header.toString()),

  // 构建头部
  builderHeader: (header) {
    return Row(
      children: [
        Container(
          padding: const EdgeInsets.fromLTRB(25, 5, 25, 5),
          margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(5.0),
            color: Colors.grey,
          ),
          child: SizedBox(child: Text('Header $header')),
        )
      ],
    );
  },

  // 内容
  content: List.generate(
    5,
    (header) => List.generate(
      10,
      (content) {
        return "$header --- Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
            "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet venenatis ";
      },
    ),
  ),

  // 构建内容
  builderContent: (content) {
    return Container(
      padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
      margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.blue,
        ),
      ),
      child: Text(content),
    );
  },
),

定义一个头部项及其构建器

// 头部
header: List.generate(5, (header) => header.toString()),

// 构建头部
builderHeader: (header) {
  return Row(
    children: [
      Container(
        padding: const EdgeInsets.fromLTRB(25, 5, 25, 5),
        margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5.0),
          color: Colors.grey,
        ),
        child: SizedBox(child: Text('Header $header')),
      )
    ],
  );
},

定义一个内容项及其构建器

// 内容
content: List.generate(
  5,
  (header) => List.generate(
    10,
    (content) {
      return "$header --- Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
          "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet venenatis ";
    },
  ),
),

// 构建内容
builderContent: (content) {
  return Container(
    padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
    margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
    decoration: BoxDecoration(
      border: Border.all(
        color: Colors.blue,
      ),
    ),
    child: Text(content),
  );
},

滚动到列表项

...
final _itemScrollController = StickyItemScrollController();

void onClicked(int index){
  _itemScrollController.scrollTo(
    index: index,
    duration: const Duration(milliseconds: 500),
  );
}

[@override](/user/override)
Widget build(BuildContext context) {
  return LazyStickyHeaders<String, String>(
    ...
    scrollController: _itemScrollController,
    
    ...
  );
}

示例代码

import 'dart:io';
import 'dart:math';

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

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  final _itemScrollController = StickyItemScrollController();
  List<String>? header;
  List<List<String>>? content;

  [@override](/user/override)
  void initState() {
    super.initState();
    checkPlatformState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      Future.delayed(
        const Duration(seconds: 2),
        () {
          header = List.generate(5, (header) => header.toString());
          content = List.generate(
            5,
            (header) => List.generate(
              20,
              (content) {
                return "$header --- Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
                    "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet venenatis ";
              },
            ),
          );

          setState(() {});
        },
      );
    });
  }

  Future<void> checkPlatformState() async {
    if (Platform.isLinux || Platform.isMacOS || Platform.isWindows || Platform.isFuchsia) {
      throw Exception("Unsupported platforms");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // 随机跳转到不同的项索引。
            // 确保索引不超过头部和内容的数量。
            var index = Random.secure().nextInt(105);
            debugPrint('Scrolling to $index');

            _itemScrollController.scrollTo(
              index: index,
              duration: const Duration(milliseconds: 500),
            );
          },
          child: const Icon(Icons.run_circle_outlined),
        ),
        appBar: AppBar(
          title: const Text('Lazy Sticky Headers'),
        ),
        body: LazyStickyHeaders<String, String>(
          scrollPhysics: const AlwaysScrollableScrollPhysics(parent: BouncingScrollPhysics()),
          scrollController: _itemScrollController,

          // 加载器
          loader: const Center(child: CircularProgressIndicator()),

          // 头部
          header: header,

          // 构建头部
          builderHeader: (header) {
            return Row(
              children: [
                Container(
                  padding: const EdgeInsets.fromLTRB(25, 5, 25, 5),
                  margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(5.0),
                    color: Colors.grey,
                  ),
                  child: SizedBox(child: Text('Header $header')),
                )
              ],
            );
          },

          // 内容
          content: content,

          // 构建内容
          builderContent: (content) {
            return Container(
              padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
              margin: const EdgeInsets.fromLTRB(5, 5, 5, 5),
              decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.blue,
                ),
              ),
              child: Text(content),
            );
          },
        ),
      ),
    );
  }
}

更多关于Flutter懒加载粘性头部插件lazy_sticky_headers的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter懒加载粘性头部插件lazy_sticky_headers的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,lazy_sticky_headers 是一个用于实现懒加载和粘性头部的插件。它结合了 flutter_sticky_headerlazy_load_scrollview 的功能,允许你在滚动时动态加载数据,并在滚动过程中保持头部固定。

以下是如何使用 lazy_sticky_headers 插件的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  lazy_sticky_headers: ^0.0.1  # 请检查最新版本

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

2. 导入包

在你的 Dart 文件中导入 lazy_sticky_headers 包:

import 'package:lazy_sticky_headers/lazy_sticky_headers.dart';

3. 使用 LazyStickyHeaders

LazyStickyHeaders 是一个 CustomScrollView,它允许你定义多个带有粘性头部的懒加载列表。

以下是一个简单的示例:

class LazyStickyHeadersExample extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lazy Sticky Headers Example'),
      ),
      body: LazyStickyHeaders(
        slivers: [
          _buildStickyHeader('Header 1', 10),
          _buildStickyHeader('Header 2', 5),
          _buildStickyHeader('Header 3', 15),
        ],
        onLoadMore: () async {
          // 这里可以执行懒加载数据的操作
          await Future.delayed(Duration(seconds: 2));
          // 返回 true 表示还有更多数据可以加载,false 表示没有更多数据
          return true;
        },
      ),
    );
  }

  SliverStickyHeader _buildStickyHeader(String headerText, int itemCount) {
    return SliverStickyHeader(
      header: Container(
        height: 50.0,
        color: Colors.blue,
        padding: EdgeInsets.symmetric(horizontal: 16.0),
        alignment: Alignment.centerLeft,
        child: Text(
          headerText,
          style: TextStyle(color: Colors.white),
        ),
      ),
      sliver: SliverList(
        delegate: SliverChildBuilderDelegate(
          (context, index) {
            return ListTile(
              title: Text('Item $index'),
            );
          },
          childCount: itemCount,
        ),
      ),
    );
  }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!