Flutter BLoC场景下如何判断转发的事件实例是否属于抽象类
问题分析与解决方案
问题根源
你传入的itemSelectedEvent是一个闭包函数,它的作用是接收两个int参数后返回EditItemDeselected实例,但闭包本身并不是EditEvent类型的对象。调试器显示的{_Closure} Closure: (int, int) => EditItemDeselected也明确说明了这一点——你判断的是函数对象的类型,而非它返回值的类型,所以is判断始终返回false。
可行解决方案
方案1:使用泛型约束(推荐)
将ChildWidget改为泛型Widget,通过泛型参数标记事件类型,同时约束泛型为你的事件抽象类:
class ChildWidget<T extends Equatable> extends StatelessWidget { final T Function(int, int) itemSelectedEvent; const ChildWidget({super.key, required this.itemSelectedEvent}); @override Widget build(BuildContext context) { // 根据泛型类型判断场景 if (T == EditEvent) { // 处理普通编辑场景的逻辑 } else if (T == EditMasterEvent) { // 处理主编辑场景的逻辑 } // 生成事件时直接调用函数: // final event = itemSelectedEvent(1, 2); // context.read<YourBloc>().add(event); return // ...你的Widget结构 } }
调用时Dart会自动推断泛型类型,也可以显式指定:
// 自动推断类型 ChildWidget(itemSelectedEvent: (i, j) => EditItemDeselected(i, j)) // 显式指定类型 ChildWidget<EditEvent>(itemSelectedEvent: (i, j) => EditItemDeselected(i, j))
方案2:封装事件工厂对象
定义一个类同时封装事件生成函数和类型标记,让类型判断更直观:
class EventCreator<T extends Equatable> { final T Function(int, int) create; final Type eventType; const EventCreator(this.create, this.eventType); }
修改ChildWidget的参数:
class ChildWidget extends StatelessWidget { final EventCreator itemSelectedCreator; const ChildWidget({super.key, required this.itemSelectedCreator}); @override Widget build(BuildContext context) { if (itemSelectedCreator.eventType == EditEvent) { // 普通场景逻辑 } else if (itemSelectedCreator.eventType == EditMasterEvent) { // 主场景逻辑 } // 生成事件 final event = itemSelectedCreator.create(1, 2); return // ...你的Widget结构 } }
调用时传入封装好的对象:
ChildWidget( itemSelectedCreator: EventCreator( (i, j) => EditItemDeselected(i, j), EditEvent, ), )
方案3:传入类型标记参数
如果不想修改太多结构,可以给ChildWidget加一个类型参数直接标记场景:
class ChildWidget extends StatelessWidget { final Function(int, int) itemSelectedEvent; final Type eventType; const ChildWidget({super.key, required this.itemSelectedEvent, required this.eventType}); @override Widget build(BuildContext context) { if (eventType == EditEvent) { // 普通场景逻辑 } else if (eventType == EditMasterEvent) { // 主场景逻辑 } return // ...你的Widget结构 } }
调用时传入对应的类型:
ChildWidget( itemSelectedEvent: (i, j) => EditItemDeselected(i, j), eventType: EditEvent, )
内容的提问来源于stack exchange,提问作者w461
相关产品推荐
相关产品推荐

