Flutter动态展示插件flow_board的使用

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

Flow Board

简介

flow_board 是一个用于 Flutter 的可定制和可拖动的看板组件。您可以使用它来创建类似于 Trello 的看板工具。

开始使用

首先,在您的项目中添加 flow_board 包:

flutter pub add flow_board
flutter pub get

这将在您的包的 pubspec.yaml 文件中添加如下依赖项:

dependencies:
  flow_board: ^0.0.1

创建您的第一个看板

初始化一个 FlowBoardController 用于管理看板的数据。您可以注册回调函数以接收看板的变化。

final FlowBoardController controller = FlowBoardController(
  onMoveGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
    debugPrint('Move item from $fromIndex to $toIndex');
  },
  onMoveGroupItem: (groupId, fromIndex, toIndex) {
    debugPrint('Move $groupId:$fromIndex to $groupId:$toIndex');
  },
  onMoveGroupItemToGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
    debugPrint('Move $fromGroupId:$fromIndex to $toGroupId:$toIndex');
  },
);

提供看板的初始数据,通过初始化 FlowBoardGroupData。每个组内的卡片需要实现 FlowBoardGroupItem 类。

void initState() {
  final group1 = FlowBoardGroupData(id: "待办事项", items: [
    TextItem("卡片 1"),
    TextItem("卡片 2"),
  ]);
  final group2 = FlowBoardGroupData(id: "进行中", items: [
    TextItem("卡片 3"),
    TextItem("卡片 4"),
  ]);

  final group3 = FlowBoardGroupData(id: "已完成", items: []);

  controller.addGroup(group1);
  controller.addGroup(group2);
  controller.addGroup(group3);
  super.initState();
}

class TextItem extends FlowBoardGroupItem {
  final String s;
  TextItem(this.s);

  [@override](/user/override)
  String get id => s;
}

最后,在构建方法中返回一个 FlowBoard 组件。

[@override](/user/override)
Widget build(BuildContext context) {
  return FlowBoard(
    controller: controller,
    cardBuilder: (context, group, groupItem) {
      final textItem = groupItem as TextItem;
      return FlowBoardGroupCard(
        key: ObjectKey(textItem),
        child: Text(textItem.s),
      );
    },
    groupConstraints: const BoxConstraints.tightFor(width: 240),
  );
}

使用示例

要快速了解如何使用,请查看 /example/lib 文件夹。 首先,运行 main.dart 来玩转演示。

其次,让我们深入到 multi_board_list_example.dart 来理解几个关键组件:

  • 通过实例化一个 FlowBoard 对象来创建一个看板组件。
  • FlowBoard 对象中,您可以找到 FlowBoardController,它在 board_data.dart 中定义,并用预填充的模拟数据填充。它还包含回调函数以实现未来的用户数据。
  • 三个生成器:FlowBoardHeaderBuilderFlowBoardFooterBuilderFlowBoardCardBuilder。下图展示了它们的作用。

术语表

请参阅 API 文档。

贡献

贡献使开源社区成为一个学习、启发和创造的绝佳场所。任何贡献都将受到极大的赞赏。

致谢

该包是 appflowy-board 的修改版本。您可以在 这里 找到原始包的许可证。

许可证

此包根据 MIT 许可证分发。详情请参阅 许可证文件


### 完整示例 Demo

以下是一个完整的示例 Demo,展示了如何使用 `flow_board` 插件创建一个简单的看板应用。

```dart
import 'package:flutter/material.dart';
import 'single_board_list_example.dart';
import 'multi_board_list_example.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> {
  int _currentIndex = 0;
  final _bottomNavigationColor = Colors.blue;

  final List<Widget> _examples = [
    const MultiBoardListExample(),
    const SingleBoardListExample(),
  ];

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('FlowBoard 看板'),
        ),
        body: Container(color: Colors.white, child: _examples[_currentIndex]),
        bottomNavigationBar: BottomNavigationBar(
          fixedColor: _bottomNavigationColor,
          showSelectedLabels: true,
          showUnselectedLabels: false,
          currentIndex: _currentIndex,
          items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.grid_on, color: _bottomNavigationColor),
                label: "多列"),
            BottomNavigationBarItem(
                icon: Icon(Icons.grid_on, color: _bottomNavigationColor),
                label: "单列"),
          ],
          onTap: (int index) {
            setState(() {
              _currentIndex = index;
            });
          },
        ),
      ),
    );
  }
}

单列看板示例

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

class SingleBoardListExample extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final FlowBoardController controller = FlowBoardController(
      onMoveGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
        debugPrint('Move item from $fromIndex to $toIndex');
      },
      onMoveGroupItem: (groupId, fromIndex, toIndex) {
        debugPrint('Move $groupId:$fromIndex to $groupId:$toIndex');
      },
      onMoveGroupItemToGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
        debugPrint('Move $fromGroupId:$fromIndex to $toGroupId:$toIndex');
      },
    );

    void initState() {
      final group1 = FlowBoardGroupData(id: "待办事项", items: [
        TextItem("卡片 1"),
        TextItem("卡片 2"),
      ]);
      final group2 = FlowBoardGroupData(id: "进行中", items: [
        TextItem("卡片 3"),
        TextItem("卡片 4"),
      ]);

      final group3 = FlowBoardGroupData(id: "已完成", items: []);

      controller.addGroup(group1);
      controller.addGroup(group2);
      controller.addGroup(group3);
    }

    class TextItem extends FlowBoardGroupItem {
      final String s;
      TextItem(this.s);

      [@override](/user/override)
      String get id => s;
    }

    return FlowBoard(
      controller: controller,
      cardBuilder: (context, group, groupItem) {
        final textItem = groupItem as TextItem;
        return FlowBoardGroupCard(
          key: ObjectKey(textItem),
          child: Text(textItem.s),
        );
      },
      groupConstraints: const BoxConstraints.tightFor(width: 240),
    );
  }
}

多列看板示例

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

class MultiBoardListExample extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final FlowBoardController controller = FlowBoardController(
      onMoveGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
        debugPrint('Move item from $fromIndex to $toIndex');
      },
      onMoveGroupItem: (groupId, fromIndex, toIndex) {
        debugPrint('Move $groupId:$fromIndex to $groupId:$toIndex');
      },
      onMoveGroupItemToGroup: (fromGroupId, fromIndex, toGroupId, toIndex) {
        debugPrint('Move $fromGroupId:$fromIndex to $toGroupId:$toIndex');
      },
    );

    void initState() {
      final group1 = FlowBoardGroupData(id: "待办事项", items: [
        TextItem("卡片 1"),
        TextItem("卡片 2"),
      ]);
      final group2 = FlowBoardGroupData(id: "进行中", items: [
        TextItem("卡片 3"),
        TextItem("卡片 4"),
      ]);

      final group3 = FlowBoardGroupData(id: "已完成", items: []);

      controller.addGroup(group1);
      controller.addGroup(group2);
      controller.addGroup(group3);
    }

    class TextItem extends FlowBoardGroupItem {
      final String s;
      TextItem(this.s);

      [@override](/user/override)
      String get id => s;
    }

    return FlowBoard(
      controller: controller,
      cardBuilder: (context, group, groupItem) {
        final textItem = groupItem as TextItem;
        return FlowBoardGroupCard(
          key: ObjectKey(textItem),
          child: Text(textItem.s),
        );
      },
      groupConstraints: const BoxConstraints.tightFor(width: 240),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用flow_board插件来动态展示内容的示例代码。flow_board是一个可以动态添加和删除子项的插件,非常适合用于展示列表、卡片等动态内容。

首先,确保你已经在pubspec.yaml文件中添加了flow_board依赖:

dependencies:
  flutter:
    sdk: flutter
  flow_board: ^最新版本号  # 请替换为实际的最新版本号

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

以下是一个完整的示例代码,展示了如何使用flow_board插件来动态添加和删除内容:

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

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

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

class FlowBoardScreen extends StatefulWidget {
  @override
  _FlowBoardScreenState createState() => _FlowBoardScreenState();
}

class _FlowBoardScreenState extends State<FlowBoardScreen> {
  final List<FlowBoardItem> _items = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flow Board Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            FlowBoard(
              items: _items,
              itemBuilder: (context, index) {
                return FlowBoardItemWidget(
                  item: _items[index],
                  onRemove: () {
                    setState(() {
                      _items.removeAt(index);
                    });
                  },
                );
              },
            ),
            SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _items.add(FlowBoardItem(
                    key: ValueKey(_items.length), // 确保每个item都有唯一的key
                    content: Text('Item ${_items.length + 1}'),
                  ));
                });
              },
              child: Text('Add Item'),
            ),
          ],
        ),
      ),
    );
  }
}

class FlowBoardItemWidget extends StatelessWidget {
  final FlowBoardItem item;
  final VoidCallback onRemove;

  FlowBoardItemWidget({required this.item, required this.onRemove});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Row(
          children: [
            Expanded(
              child: item.content,
            ),
            IconButton(
              icon: Icon(Icons.close),
              onPressed: onRemove,
            ),
          ],
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖引入:在pubspec.yaml文件中引入flow_board插件。
  2. 主应用MyApp类定义了一个基本的Flutter应用。
  3. 主屏幕FlowBoardScreen是一个有状态的Widget,用于管理Flow Board的项(_items)。
  4. Flow Board:使用FlowBoard组件展示动态内容。itemBuilder方法用于构建每个项。
  5. 添加项:通过点击“Add Item”按钮,动态地向_items列表中添加新的FlowBoardItem
  6. 删除项:每个FlowBoardItemWidget都有一个删除按钮,点击时会从_items列表中移除对应的项。

注意:FlowBoardItemflow_board插件中的一个类,用于表示Flow Board中的每一项。你需要根据插件的实际API文档调整代码。

希望这个示例能帮助你理解如何在Flutter项目中使用flow_board插件来动态展示内容。

回到顶部