Flutter可重排交错滚动视图插件reorderable_staggered_scroll_view的使用

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

Flutter可重排交错滚动视图插件reorderable_staggered_scroll_view的使用

描述

reorderable_staggered_scroll_view 是一个Flutter包,用于创建可重排序和可拖拽的交错网格和列表视图。此包提供了一种平滑且直观的方式在网格和列表布局中重新排列项目,非常适合创建交互性和用户友好型的应用程序。

特性

  • 使用简单的拖放手势即可轻松重新排序项目。
  • 支持交错网格和列表布局。
  • 可配置的拖放行为。
  • 旨在为用户提供无缝体验。

开始使用

要在您的项目中使用这个包,您需要将其添加到 pubspec.yaml 文件中,并替换 ^latest_version 为实际想要使用的版本号:

dependencies:
  reorderable_staggered_scroll_view: ^latest_version

然后,在Dart代码中导入该包:

import 'package:reorderable_staggered_scroll_view/reorderable_staggered_scroll_view.dart';

示例代码

以下是一个完整的示例应用程序,展示了如何使用 reorderable_staggered_scroll_view 创建一个可以切换不同类型的页面(列表、固定数量的网格、自定义宽度的网格)的应用程序:

import 'dart:math';

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Builder(builder: (context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Example'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                for (final type in GridType.values)
                  Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: ElevatedButton(
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => HomePage(type: type),
                          ),
                        );
                      },
                      child: Padding(
                        padding: const EdgeInsets.all(16),
                        child: Text(switch (type) {
                          GridType.list => "List",
                          GridType.count => "Grid Count",
                          GridType.extent => "Grid Extent",
                        }),
                      ),
                    ),
                  ),
              ],
            ),
          ),
        );
      }),
    );
  }
}

enum GridType {
  list,
  count,
  extent,
}

class HomePage extends StatefulWidget {
  final GridType type;

  const HomePage({Key? key, required this.type}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _dragEnabled = true;

  @override
  Widget build(BuildContext context) {
    final nonDraggable = ReorderableStaggeredScrollViewGridCountItem(
      key: ValueKey(10.toString()),
      mainAxisCellCount: 1,
      crossAxisCellCount: Random().nextInt(2) + 1,
      widget: const Card(
        child: Padding(
          padding: EdgeInsets.all(12),
          child: Center(child: Text('Non Draggable')),
        ),
      ),
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(switch (widget.type) {
          GridType.list => "List Example",
          GridType.count => "Grid Count Example",
          GridType.extent => "Grid Extent Example",
        }),
        actions: [
          IconButton(
            onPressed: () {
              setState(() {
                _dragEnabled = !_dragEnabled;
              });
            },
            icon: Icon(
              _dragEnabled ? Icons.pause : Icons.play_arrow,
            ),
          )
        ],
      ),
      body: widget.type == GridType.list
          ? ReorderableStaggeredScrollView.list(
              enable: _dragEnabled,
              padding: const EdgeInsets.all(16),
              physics: const BouncingScrollPhysics(),
              scrollDirection: Axis.vertical,
              axis: Axis.vertical,
              shrinkWrap: true,
              isLongPressDraggable: false,
              onDragEnd: (details, item) {
                debugPrint('onDragEnd: $details ${item.key}');
              },
              isNotDragList: [nonDraggable],
              children: [
                ...List.generate(
                  5,
                  (index) => ReorderableStaggeredScrollViewListItem(
                    key: ValueKey(index.toString()),
                    widget: Card(
                      child: Padding(
                        padding: const EdgeInsets.all(12),
                        child: Center(child: Text('Item $index')),
                      ),
                    ),
                  ),
                ),
                nonDraggable,
                ...List.generate(
                  5,
                  (index) => ReorderableStaggeredScrollViewListItem(
                    key: ValueKey('${index + 5}'),
                    widget: Card(
                      child: Padding(
                        padding: const EdgeInsets.all(12),
                        child: Center(child: Text('Item ${index + 5}')),
                      ),
                    ),
                  ),
                )
              ])
          : ReorderableStaggeredScrollView.grid(
              enable: _dragEnabled,
              padding: const EdgeInsets.all(16),
              scrollDirection: Axis.vertical,
              physics: const BouncingScrollPhysics(),
              crossAxisCount: 4,
              isLongPressDraggable: false,
              onAccept: (item1, item2, value) {
                print('item1 $item1 item2 $item2 value $value');
              },
              onDragEnd: (details, item) {
                print('onDragEnd: $details ${item.key}');
              },
              onMove: (item, item2, value) {
                print('onMove: item $item item2 $item2 value $value');
              },
              onDragUpdate: (details, item) {
                print('onDragUpdate: details $details item $item');
              },
              isNotDragList: [nonDraggable],
              children: [
                ...List.generate(
                  5,
                  (index) => widget.type == GridType.count
                      ? ReorderableStaggeredScrollViewGridCountItem(
                          key: ValueKey(index.toString()),
                          mainAxisCellCount: 1,
                          crossAxisCellCount: Random().nextInt(2) + 1,
                          widget: Card(
                              child: Center(child: Text('Item $index'))),
                        )
                      : ReorderableStaggeredScrollViewGridExtentItem(
                          key: ValueKey(index.toString()),
                          mainAxisExtent: Random().nextInt(200) + 100,
                          crossAxisCellCount: Random().nextInt(2) + 1,
                          widget: Card(
                              child: Center(child: Text('Item $index'))),
                        ),
                ),
                nonDraggable,
                ...List.generate(
                  5,
                  (index) => widget.type == GridType.count
                      ? ReorderableStaggeredScrollViewGridCountItem(
                          key: ValueKey((index + 5).toString()),
                          mainAxisCellCount: 1,
                          crossAxisCellCount: Random().nextInt(2) + 1,
                          widget: Card(
                              child: Center(child: Text('Item ${index + 5}'))),
                        )
                      : ReorderableStaggeredScrollViewGridExtentItem(
                          key: ValueKey((index + 5).toString()),
                          mainAxisExtent: Random().nextInt(200) + 100,
                          crossAxisCellCount: Random().nextInt(2) + 1,
                          widget: Card(
                              child: Center(child: Text('Item ${index + 5}'))),
                        ),
                )
              ]),
    );
  }
}

上述代码创建了一个包含三个按钮的主界面,每个按钮点击后都会导航到一个新页面,展示不同类型的视图(列表、固定数量的网格、自定义宽度的网格)。这些页面中的元素支持拖动以重新排序,并且可以通过应用栏上的图标启用或禁用拖动功能。此外,还展示了如何创建不可拖动的项。


更多关于Flutter可重排交错滚动视图插件reorderable_staggered_scroll_view的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter可重排交错滚动视图插件reorderable_staggered_scroll_view的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 reorderable_staggered_scroll_view 插件的示例代码。这个插件结合了 Flutter 的交错滚动视图(StaggeredGridView)和可重排列表(ReorderableListView)的功能,允许用户在一个交错布局中重新排列项目。

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

dependencies:
  flutter:
    sdk: flutter
  reorderable_staggered_scroll_view: ^0.1.0  # 请检查最新版本号

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

以下是一个完整的示例代码,展示如何在 Flutter 应用中使用 reorderable_staggered_scroll_view

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

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

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

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Reorderable Staggered Scroll View Demo'),
      ),
      body: ReorderableStaggeredGridView.countBuilder(
        crossAxisCount: 2,
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            key: ValueKey(items[index]),
            child: ListTile(
              title: Text(items[index]),
            ),
          );
        },
        staggeredTileBuilder: (int index) => StaggeredTile.count(2, index % 2 + 1),
        onReorder: (int oldIndex, int newIndex) {
          setState(() {
            final String item = items.removeAt(oldIndex);
            items.insert(newIndex, item);
          });
        },
      ),
    );
  }
}

代码说明:

  1. 依赖引入:确保在 pubspec.yaml 中引入了 reorderable_staggered_scroll_view 插件。
  2. 主应用MyApp 类是应用的入口,它创建一个 MaterialApp 并设置主页为 MyHomePage
  3. 主页MyHomePage 是一个有状态的小部件,它维护一个字符串列表 items
  4. 构建界面
    • 使用 Scaffold 小部件来创建应用的主体结构,包括一个 AppBar
    • 使用 ReorderableStaggeredGridView.countBuilder 构建交错滚动视图,其中:
      • crossAxisCount 指定交叉轴上的项目数。
      • itemCount 指定项目总数。
      • itemBuilder 用于构建每个项目的小部件,这里使用 CardListTile
      • staggeredTileBuilder 用于指定每个项目的交错布局,这里使用 StaggeredTile.count 方法来创建不同高度的瓦片。
      • onReorder 回调用于处理项目的重新排列逻辑,它接收旧索引和新索引,并在列表中相应地移动项目。

运行这个示例代码,你将看到一个可以交错滚动和重新排列项目的列表。你可以拖动项目以重新排列它们,并且布局会自动调整以适应新的顺序。

回到顶部