원클릭으로
event-listener-container
为Flutter插件视图添加事件监听容器,自动管理事件订阅/取消订阅生命周期,避免内存泄漏并减少约84%的模板代码。适用场景:(1) 插件视图需要响应全局事件更新UI,(2) 需要避免手动管理订阅导致的内存泄漏,(3) 简化事件监听实现
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
为Flutter插件视图添加事件监听容器,自动管理事件订阅/取消订阅生命周期,避免内存泄漏并减少约84%的模板代码。适用场景:(1) 插件视图需要响应全局事件更新UI,(2) 需要避免手动管理订阅导致的内存泄漏,(3) 简化事件监听实现
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
迁移小组件到事件携带数据模式,优化刷新性能。将数据直接放在事件中传递,小组件直接使用事件数据,避免重复的缓存访问操作。
确保小组件组件根据 HomeWidgetSize 正确调整各元素大小,包括容器、图标、字体、间距、线条粗细等
为插件主页添加带过滤器的列表小组件,使用 commonWidgetsProvider 支持多种公共组件样式,根据过滤条件选择使用多步骤 data selectors 或自定义表单
将插件中内置的dataRenderer(自定义UI)封装成标准的公共小组件,使其可被其他插件或功能复用。核心特性:(1)提取dataRenderer的UI逻辑创建独立组件文件,(2)在common_widgets.dart中注册新组件,(3)在_provideCommonWidgets中添加数据提供函数,(4)移除旧的内置渲染器代码
从 code_snippet 原型文件创建可预览的 Dart 小组件。自动分析 HTML 设计、生成 Flutter 组件、注册路由并添加到组件展示列表。
为Flutter插件添加可配置的选择器小组件(HomeWidget),支持用户点击配置、数据选择和动态数据渲染。核心特性:(1) 配置dataSelector保存必要数据,(2) 通过controller传递id获取最新数据,(3) 支持导航到详情页
| name | event-listener-container |
| description | 为Flutter插件视图添加事件监听容器,自动管理事件订阅/取消订阅生命周期,避免内存泄漏并减少约84%的模板代码。适用场景:(1) 插件视图需要响应全局事件更新UI,(2) 需要避免手动管理订阅导致的内存泄漏,(3) 简化事件监听实现 |
为Flutter插件视图添加事件监听容器,自动管理事件订阅生命周期。
识别以下内容:
task_added, task_updated)setState() 或控制器方法调用)import 'package:Memento/widgets/event_listener_container.dart';
在需要响应事件的 UI 外层包裹组件:
EventListenerContainer(
events: ['task_added', 'task_updated', 'task_deleted'],
onEvent: () => setState(() {}),
child: MyContentWidget(),
)
当同时依赖控制器状态和事件时:
EventListenerContainer(
events: ['task_added', 'task_updated', 'task_deleted'],
onEvent: () {}, // 事件触发但不直接更新
child: AnimatedBuilder(
animation: myController,
builder: (context, _) {
return MyContentWidget(data: myController.data);
},
),
)
同一页面可以有多个独立的监听器:
Column(
children: [
// 监听数据变更事件
EventListenerContainer(
events: ['data_changed'],
onEvent: () => setState(() => _dataVersion++),
child: DataDisplayWidget(),
),
// 监听UI相关事件
EventListenerContainer(
events: ['theme_changed', 'locale_changed'],
onEvent: () => _refreshTheme(),
child: ThemedWidget(),
),
],
)
在 onEvent 中添加条件判断:
EventListenerContainer(
events: ['item_added', 'item_updated', 'item_deleted'],
onEvent: () {
final eventName = EventManager.instance.getLatestEventName() ?? '';
if (eventName == 'item_deleted' && shouldSkipDeleteUpdate) {
return;
}
setState(() {});
},
child: MyContentWidget(),
)
查找以下模式的事件名称:
| 事件类型 | 命名示例 | 说明 |
|---|---|---|
| 添加 | task_added, note_created | 使用过去式 |
| 更新 | task_updated, settings_changed | 使用过去式 |
| 删除 | task_deleted, item_removed | 使用过去式 |
| 完成 | task_completed, goal_achieved | 使用过去式 |
| 状态变更 | status_changed, visibility_updated | 使用过去式 |
查找以下模式:
ChangeNotifierAnimatedBuilder 响应控制器变化refreshFromRemote() 或类似方法class MyView extends StatefulWidget {
const MyView({super.key});
@override
State<MyView> createState() => _MyViewState();
}
class _MyViewState extends State<MyView> {
final List<(String, void Function(EventArgs))> _subscriptions = [];
@override
void initState() {
super.initState();
_registerListeners();
}
void _registerListeners() {
void handler1(EventArgs args) {
if (mounted) setState(() {});
}
EventManager.instance.subscribe('task_added', handler1);
_subscriptions.add(('task_added', handler1));
// ... 更多事件
}
@override
void dispose() {
for (final (eventName, handler) in _subscriptions) {
EventManager.instance.unsubscribe(eventName, handler);
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(children: [...]);
}
}
class MyView extends StatelessWidget {
const MyView({super.key});
@override
Widget build(BuildContext context) {
return EventListenerContainer(
events: ['task_added', 'task_updated', 'task_deleted'],
onEvent: () => setState(() {}),
child: Column(children: [...]),
);
}
}
代码量对比:
只在需要响应事件的最小 UI 区域使用,避免不必要的重建。
将相关事件分组,不要一次性监听所有事件。
对于复杂逻辑,将更新逻辑封装在控制器中,onEvent 只调用控制器方法:
EventListenerContainer(
events: ['external_sync_event'],
onEvent: () => myController.refreshFromRemote(),
child: AnimatedBuilder(
animation: myController,
builder: (context, _) => ListView(...),
),
)
如果多个事件可能连续触发,考虑使用防抖:
bool _isUpdating = false;
EventListenerContainer(
events: ['batch_update'],
onEvent: () {
if (_isUpdating) return;
_isUpdating = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
_isUpdating = false;
setState(() {});
});
},
child: MyContentWidget(),
)
检查:
EventListenerContainer 是否正确包裹了目标 UIonEvent 回调中是否调用了 setState() 或触发更新的方法通过 EventManager.instance.getLatestEvent() 获取:
EventListenerContainer(
events: ['item_added'],
onEvent: () {
final latestEvent = EventManager.instance.getLatestEvent('item_added');
if (latestEvent != null && latestEvent is ItemEventArgs) {
print('添加的项目ID: ${latestEvent.itemId}');
}
setState(() {});
},
child: MyContentWidget(),
)
不会。每个 EventListenerContainer 都是独立的订阅者,只会更新各自的子树。
initState 自动订阅,dispose 自动取消订阅EventListenerContainer 独立工作,不会相互干扰flutter analyze 验证代码