Flutter文本编辑增强插件flow_compose的使用
Flutter文本编辑增强插件flow_compose的使用
本文将介绍如何使用Flutter中的文本编辑增强插件flow_compose
。此插件旨在帮助构建AI代理或其他流程图工具。
插件功能概述
flow_compose
插件可以帮助开发者轻松地在Flutter应用中实现复杂的流程图编辑功能。通过这个插件,你可以创建可交互的流程图,并且能够动态添加、删除节点和边。
示例代码
以下是一个完整的示例代码,展示了如何使用flow_compose
插件来创建一个简单的流程图编辑器。
import 'dart:convert';
import 'package:example/nodes/sql_node.dart';
import 'package:example/style.dart';
import 'package:example/workflow/workflow_graph.dart';
import 'package:flow_compose/flow_compose.dart';
import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:flutter_json_view/flutter_json_view.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:toastification/toastification.dart';
import 'nodes/login_node.dart';
import 'nodes/simple_qa_node.dart';
import 'nodes/start_node.dart';
import 'workflow/workflow_notifier.dart';
void main() {
runApp(ToastificationWrapper(
child: ProviderScope(child: MyApp()),
));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends ConsumerStatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
ConsumerState<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends ConsumerState<MyHomePage> {
@override
Widget build(BuildContext context) {
final controller = ref.read(workflowProvider.notifier).controller;
return Scaffold(
body: InfiniteDrawingBoard(
controller: controller,
),
floatingActionButtonLocation: ExpandableFab.location,
floatingActionButton: ExpandableFab(
distance: 50,
type: ExpandableFabType.up,
children: [
FloatingActionButton.small(
tooltip: "重新居中",
heroTag: null,
child: const Icon(Icons.center_focus_strong),
onPressed: () {
controller.reCenter();
},
),
FloatingActionButton.small(
tooltip: "清除",
heroTag: null,
child: const Icon(Icons.clear_all),
onPressed: () {
controller.clear();
},
),
FloatingActionButton.small(
tooltip: "执行",
heroTag: null,
child: const Icon(Icons.start),
onPressed: () {
WorkflowGraph graph = WorkflowGraph(controller.state.value.data,
controller.state.value.edges.toList());
Future.microtask(() async {
graph.executeWorkflow(ref);
});
},
),
FloatingActionButton.small(
tooltip: "从JSON导入",
heroTag: null,
child: const Icon(Icons.edit),
onPressed: () {
final textController = TextEditingController();
showGeneralDialog(
barrierDismissible: true,
barrierLabel: "json",
context: context,
pageBuilder: (c, _, __) {
return Center(
child: Material(
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
width: 600,
height: 400,
child: TextField(
controller: textController,
decoration: inputDecoration,
maxLines: 20,
),
),
),
);
}).then((_) {
if (textController.text.isNotEmpty) {
Map<String, dynamic> data = jsonDecode(textController.text);
List<INode> nodes = [];
List<Edge> edges = [];
for (var node in data["nodes"]) {
// nodes.add(INode.fromJson(node));
if (node['builderName'] == "StartNode") {
nodes.add(StartNode.fromJson(node));
} else if (node['builderName'] == "SqlNode") {
nodes.add(SqlNode.fromJson(node));
} else if (node['builderName'] == "SimpleQaNode") {
nodes.add(SimpleQaNode.fromJson(node));
} else if (node['builderName'] == "LoginNode") {
nodes.add(LoginNode.fromJson(node));
} else {
nodes.add(INode.fromJson(node));
}
}
for (var edge in data["edges"]) {
edges.add(Edge.fromJson(edge));
}
controller.reCreate(nodes, edges);
}
});
},
),
FloatingActionButton.small(
tooltip: "导出为JSON",
heroTag: null,
child: const Icon(Icons.abc),
onPressed: () {
debugPrint(controller.dumpToString());
showGeneralDialog(
barrierDismissible: true,
barrierLabel: "json",
context: context,
pageBuilder: (c, _, __) {
return Center(
child: Material(
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
width: 600,
height: 400,
child: JsonView.string(controller.dumpToString()),
),
),
);
});
},
),
],
),
);
}
}
功能说明
1. 重新居中 (reCenter
)
点击此按钮可以将整个流程图重新居中到屏幕中央。
FloatingActionButton.small(
tooltip: "重新居中",
heroTag: null,
child: const Icon(Icons.center_focus_strong),
onPressed: () {
controller.reCenter();
},
)
2. 清除 (clear
)
点击此按钮可以清除所有已添加的节点和边。
FloatingActionButton.small(
tooltip: "清除",
heroTag: null,
child: const Icon(Icons.clear_all),
onPressed: () {
controller.clear();
},
)
3. 执行 (execute
)
点击此按钮可以执行当前的流程图。
FloatingActionButton.small(
tooltip: "执行",
heroTag: null,
child: const Icon(Icons.start),
onPressed: () {
WorkflowGraph graph = WorkflowGraph(controller.state.value.data,
controller.state.value.edges.toList());
Future.microtask(() async {
graph.executeWorkflow(ref);
});
},
)
4. 从JSON导入 (fromJson
)
点击此按钮可以导入一个JSON文件来重新创建当前的流程图。
FloatingActionButton.small(
tooltip: "从JSON导入",
heroTag: null,
child: const Icon(Icons.edit),
onPressed: () {
final textController = TextEditingController();
showGeneralDialog(
barrierDismissible: true,
barrierLabel: "json",
context: context,
pageBuilder: (c, _, __) {
return Center(
child: Material(
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
width: 600,
height: 400,
child: TextField(
controller: textController,
decoration: inputDecoration,
maxLines: 20,
),
),
),
);
}).then((_) {
if (textController.text.isNotEmpty) {
Map<String, dynamic> data = jsonDecode(textController.text);
List<INode> nodes = [];
List<Edge> edges = [];
for (var node in data["nodes"]) {
if (node['builderName'] == "StartNode") {
nodes.add(StartNode.fromJson(node));
} else if (node['builderName'] == "SqlNode") {
nodes.add(SqlNode.fromJson(node));
} else if (node['builderName'] == "SimpleQaNode") {
nodes.add(SimpleQaNode.fromJson(node));
} else if (node['builderName'] == "LoginNode") {
nodes.add(LoginNode.fromJson(node));
} else {
nodes.add(INode.fromJson(node));
}
}
for (var edge in data["edges"]) {
edges.add(Edge.fromJson(edge));
}
controller.reCreate(nodes, edges);
}
});
},
)
5. 导出为JSON (toJson
)
点击此按钮可以将当前的流程图导出为JSON格式。
FloatingActionButton.small(
tooltip: "导出为JSON",
heroTag: null,
child: const Icon(Icons.abc),
onPressed: () {
debugPrint(controller.dumpToString());
showGeneralDialog(
barrierDismissible: true,
barrierLabel: "json",
context: context,
pageBuilder: (c, _, __) {
return Center(
child: Material(
borderRadius: BorderRadius.circular(20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
width: 600,
height: 400,
child: JsonView.string(controller.dumpToString()),
),
),
);
});
},
)
更多关于Flutter文本编辑增强插件flow_compose的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文本编辑增强插件flow_compose的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flow_compose
是一个用于 Flutter 的文本编辑增强插件,它允许开发者通过组合式的方式来构建复杂的文本编辑功能。这个插件的设计灵感来自于 Jetpack Compose,它提供了一种声明式的方式来处理文本编辑和输入。
安装
首先,你需要在 pubspec.yaml
文件中添加 flow_compose
依赖:
dependencies:
flutter:
sdk: flutter
flow_compose: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
基本用法
flow_compose
的核心是 FlowCompose
组件,它可以用来包裹你的文本编辑控件,并通过组合不同的 FlowComposeNode
来实现文本编辑的增强功能。
import 'package:flutter/material.dart';
import 'package:flow_compose/flow_compose.dart';
class MyTextEditor extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FlowCompose Example'),
),
body: FlowCompose(
child: TextField(
decoration: InputDecoration(
hintText: 'Type something...',
),
),
nodes: [
// 添加一些节点来增强文本编辑功能
FlowComposeNode(
condition: (text) => text.contains('@'),
action: (text, selection) {
// 当检测到 '@' 时,触发某些操作
print('Detected @ in text: $text');
},
),
FlowComposeNode(
condition: (text) => text.length > 10,
action: (text, selection) {
// 当文本长度超过 10 时,触发某些操作
print('Text length exceeds 10 characters');
},
),
],
),
);
}
}
节点(Nodes)
FlowComposeNode
是 flow_compose
的核心概念。每个节点包含一个 condition
和一个 action
:
condition
: 一个函数,接受当前文本作为参数,返回一个布尔值。当条件为true
时,action
会被触发。action
: 一个函数,接受当前文本和选择范围作为参数,执行某些操作。
自定义节点
你可以根据需要创建自定义的 FlowComposeNode
来实现特定的文本编辑逻辑。例如,你可以创建一个节点来检测特定的关键词并执行相应的操作。
FlowComposeNode(
condition: (text) => text.contains('flutter'),
action: (text, selection) {
// 当检测到 'flutter' 时,触发某些操作
print('Flutter mentioned!');
},
);
高级用法
flow_compose
还支持更高级的用法,例如组合多个节点、动态添加和删除节点等。你可以通过 FlowComposeController
来更精细地控制文本编辑的行为。
FlowComposeController _controller = FlowComposeController();
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Advanced FlowCompose Example'),
),
body: FlowCompose(
controller: _controller,
child: TextField(
decoration: InputDecoration(
hintText: 'Type something...',
),
),
nodes: [
// 初始节点
FlowComposeNode(
condition: (text) => text.contains('@'),
action: (text, selection) {
print('Detected @ in text: $text');
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 动态添加节点
_controller.addNode(
FlowComposeNode(
condition: (text) => text.contains('#'),
action: (text, selection) {
print('Detected # in text: $text');
},
),
);
},
child: Icon(Icons.add),
),
);
}