Flutter上下文操作栏插件contextualactionbar的使用

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

Flutter 上下文操作栏插件 Contextual Action Bar (CAB) 的使用

Flutter 目前还没有原生支持上下文操作栏(Contextual Action Bar, CAB),但通过第三方插件 flutter-contextual-action-bar,我们可以实现这一功能。本文将详细介绍如何使用该插件,并提供一个完整的示例 Demo。

什么是 CAB?

CAB 是一种顶部应用栏,用于在用户选择项目时提供相关的上下文操作。它类似于 WhatsApp 或 Gmail 中的选择模式下的操作栏。

CAB & Flutter

Flutter 尚未原生支持 CAB,但可以通过 flutter-contextual-action-bar 插件来实现。你可以参考 GitHub Issue 了解更多信息。

如何使用 flutter-contextual-action-bar

主要组件

  • ContextualScaffold
  • ContextualAppBar
  • ContextualAction
  • ContextualActionWidget

ContextualScaffold<?>()

ContextualScaffold 类似于标准的 Scaffold,但它需要一个额外的 contextualAppBar 参数。

ContextualScaffold(
  contextualAppBar: ContextualAppBar(),
  appBar: AppBar(title: Text('Contextual Action Bar Demo')),
  body: Body(),
)

你可以在页面中使用多个 ContextualScaffold

ContextualAppBar<?>()

ContextualAppBar 类似于标准的 AppBar,但它使用 counterBuilder 来显示选中的项目数量,并且用 contextualActions 替代了 actions

ContextualAppBar(
  counterBuilder: (int itemsCount) {
    return Text("$itemsCount Selected");
  },
  contextualActions: <ContextualAction>[
    ContextualAction(
      itemsHandler: (List<?> items) {
        items.forEach((item) {
          Scaffold.of(context).showSnackBar(SnackBar(
            content/XMLSchemaValidator("$item saved"),
          ));
        });
      },
      child: Icon(Icons.save),
    ),
  ],
)

ContextualAction<?>()

ContextualAction 允许你对选中的项目执行操作。通过 itemsHandler 回调函数处理选中的项目。

ContextualAction(
  itemsHandler: (List<?> items) {
    items.forEach((item) {
      Scaffold.of(context).showSnackBar(SnackBar(
        content: Text("$item saved"),
      ));
    });
  },
  child: Icon(Icons.save),
)

ContextualActionWidget<?>()

ContextualActionWidget 可以放置在 ContextualScaffoldbody 中,用来通知 ContextualScaffold 某个项目已被选中,从而显示 ContextualAppBar

ContextualActionWidget(
  data: 'Your Data',
  child: ListTile(
    title: Text('Item Title'),
  ),
)

注意:子部件不应处理 onLongPress 事件。

ContextualActionWidget 的其他参数

  • selectedColor: 选中项的背景颜色,默认为水波纹颜色。
  • selectedWidget: 在启用 ActionMode 并选中项时显示的部件。
  • unselectedWidget: 在启用 ActionMode 但未选中项时显示的部件。

ActionMode

  • 使用 ActionMode.addItem<?> 添加一个项目到已选列表。如果这是第一个选中的项目,则会启用 ActionMode
  • 使用 ActionMode.addItems<?> 添加一组项目。
  • 使用 ActionMode.disable<?> 禁用并取消所有选中的项目。
  • 使用 ActionMode.enabledStream<?> 发射 truefalse,表示 ActionMode 是否启用。

示例代码

以下是一个完整的示例代码,演示如何在 Flutter 应用中使用 flutter-contextual-action-bar 插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Contextual Action Bar Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primarySwatch: Colors.teal),
      home: Scaffold(
        body: WhatsAppExample(),
      ),
    );
  }
}

class WhatsAppExample extends StatefulWidget {
  @override
  _WhatsAppExampleState createState() => _WhatsAppExampleState();
}

class _WhatsAppExampleState extends State<WhatsAppExample> {
  @override
  Widget build(BuildContext context) {
    return ContextualScaffold(
      contextualAppBar: ContextualAppBar(
        counterBuilder: (int itemsCount) {
          return Text("$itemsCount Selected");
        },
        contextualActions: <ContextualAction>[
          ContextualAction(
            itemsHandler: (List<?> items) {
              items.forEach((item) {
                Scaffold.of(context).showSnackBar(SnackBar(
                  content: Text("$item saved"),
                ));
              });
            },
            child: Icon(Icons.save),
          ),
        ],
      ),
      appBar: AppBar(title: Text('WhatsApp Example')),
      body: ListView.builder(
        itemCount: 20,
        itemBuilder: (context, index) {
          return ContextualActionWidget(
            data: 'Item $index',
            child: ListTile(
              title: Text('Item $index'),
            ),
          );
        },
      ),
    );
  }
}

总结

通过 flutter-contextual-action-bar 插件,我们可以在 Flutter 应用中轻松实现上下文操作栏的功能。这个插件提供了灵活的方式来管理选中的项目,并根据用户选择显示相应的操作按钮。希望本文对你有所帮助!如果你喜欢这个项目,请记得给它点个 Star ⭐️!

完整示例可以查看 example page


更多关于Flutter上下文操作栏插件contextualactionbar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter上下文操作栏插件contextualactionbar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,虽然没有一个官方的名为 contextualactionbar 的插件,但我们可以通过自定义组件和状态管理来实现类似上下文操作栏(Contextual Action Bar, CAB)的功能。这种功能通常用于在列表项上执行批量操作,类似于Android中的CAB。

以下是一个简单的例子,展示如何在Flutter中实现一个上下文操作栏。这个例子将包括一个列表视图,当用户长按某个列表项时,会显示一个操作栏,允许用户选择多个项目并执行某些操作。

首先,我们需要创建一个Flutter项目并添加必要的依赖项(虽然这个例子不依赖于任何特定包,但你可能需要一些基本的UI库,如 flutter/material)。

  1. 项目结构

    my_flutter_app/
    ├── lib/
    │   ├── main.dart
    │   └── contextual_action_bar.dart
    └── pubspec.yaml
    
  2. pubspec.yaml 文件(确保包含基本的 Flutter 依赖):

    name: my_flutter_app
    description: A new Flutter application.
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.12.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
    flutter:
      uses-material-design: true
    
  3. main.dart 文件:

    import 'package:flutter/material.dart';
    import 'contextual_action_bar.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Contextual Action Bar Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Scaffold(
            appBar: AppBar(
              title: Text('Contextual Action Bar Demo'),
            ),
            body: ContextualActionBarDemo(),
          ),
        );
      }
    }
    
  4. contextual_action_bar.dart 文件:

    import 'package:flutter/material.dart';
    
    class ContextualActionBarDemo extends StatefulWidget {
      @override
      _ContextualActionBarDemoState createState() => _ContextualActionBarDemoState();
    }
    
    class _ContextualActionBarDemoState extends State<ContextualActionBarDemo> with SingleTickerProviderStateMixin {
      final List<String> items = List.generate(20, (i) => "Item ${i + 1}");
      final Set<int> selectedIndices = Set<int>();
      bool isActionModeActive = false;
      int? selectedIndexForActionMode;
    
      @override
      Widget build(BuildContext context) {
        return ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return GestureDetector(
              onLongPress: () {
                setState(() {
                  selectedIndexForActionMode = index;
                  selectedIndices.clear();
                  selectedIndices.add(index);
                  isActionModeActive = true;
                });
                showContextualActionBar(context, index);
              },
              child: ListTile(
                leading: Checkbox(
                  value: selectedIndices.contains(index),
                  onChanged: (newValue) {
                    setState(() {
                      if (newValue) {
                        selectedIndices.add(index);
                      } else {
                        selectedIndices.remove(index);
                      }
                    });
                  },
                  tristate: true,
                ),
                title: Text(items[index]),
              ),
            );
          },
        );
      }
    
      void showContextualActionBar(BuildContext context, int index) {
        final scaffoldMessenger = ScaffoldMessenger.of(context);
        final snackBar = SnackBar(
          content: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text('Selected: ${selectedIndices.length} items'),
              ElevatedButton(
                onPressed: () {
                  // Perform action on selected items
                  print("Performing action on selected items: ${selectedIndices.toList()}");
                  setState(() {
                    isActionModeActive = false;
                    selectedIndices.clear();
                  });
                  scaffoldMessenger.hideCurrentSnackBar();
                },
                child: Text('Perform Action'),
              ),
              IconButton(
                icon: Icon(Icons.clear),
                onPressed: () {
                  setState(() {
                    isActionModeActive = false;
                    selectedIndices.clear();
                  });
                  scaffoldMessenger.hideCurrentSnackBar();
                },
              ),
            ],
          ),
          behavior: SnackBarBehavior.floating,
          duration: Duration.indefinite,
          action: SnackBarAction(
            label: 'Cancel',
            onPressed: () {
              setState(() {
                isActionModeActive = false;
                selectedIndices.clear();
              });
              scaffoldMessenger.hideCurrentSnackBar();
            },
          ),
        );
    
        scaffoldMessenger.showSnackBar(snackBar);
      }
    }
    

在这个例子中,我们使用了 ListView.builder 来生成一个列表,每个列表项都是一个 ListTile,前面有一个 Checkbox。当用户长按某个列表项时,会触发 onLongPress 回调,显示一个类似于CAB的 SnackBar,允许用户执行操作或取消选择。

请注意,这个实现是基本的,并且为了简单起见,使用了 SnackBar 来模拟CAB。在实际应用中,你可能需要更复杂的布局和动画来实现一个更贴近原生Android CAB的用户体验。

回到顶部