欢迎转载,转载请标明出处.
英文原文文档地址: Litho-doc
事件处理
概述
框架提供了一套多用途的API用来在事件发生的时候与Component通信.事件被声明成一个POJO并且使用@Event注释.为了方便,我们命名事件类时使用Event作为后缀.事件的类不一定必须是LayoutSpec或者MountSpec的内部类.这是因为从设计上看,Spec一般被认为是私有的概念,而事件却可以允许被多个Component使用.
1 2 3 4
| @Event public class ColorChangedEvent { public int color; }
|
在这个例子中我们假设我们有一个Component名叫ColorComponent.为了指明一个ColorComponent可以分发ColorChangedEvent事件,我们的ColorComponentSpec必须在注释中注明这一点.注明的方式是使用@MountSpec或者@LayoutSpec注释中的events参数.一个Component的注释可以分派多个事件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @LayoutSpec(events = { ColorChangedEvent.class }) class ColorComponentSpec { ... @OnCreateLayout static ComponentLayout onCreateLayout( Context c, @Prop EventHandler colorChangedHandler, @FromPrepare int color) { ... ColorComponent.dispatchColorChangedEvent( colorChangedHandler, color); ... } }
|
对一个FooEvent类型的事件,将会自动生成一个对应的dispatchFooEvent方法和一个供事件回调使用的事件标识符.
dispatchFooEvent方法使用一个EventHandler作为第一个参数,它后面紧跟着的参数是你在@Event类中定义的参数的列表.我们规定为每一个你的Component暴露出的事件使用一个EventHandler prop.
在上面的例子中,ColorComponent使用一个colorChangedHandler作为prop,并且使用自动生成的dispatchColorChangedEvent()方法把ColorChangedEvent分发给它.
回调
为了处理其他Component分发过来的事件,你需要一个EventHandler实例和一个匹配的回调.
你可以使用自动生成的Component中的相对应的eventHandler factory方法来创建EventHandler实例.这个方法的名称将会和你的事件回调方法的名称相同.
你可以使用@OnEvent注释定义事件回调.@OnEvent将接受一个参数:事件类.这个方法的第一个参数必须是一个ComponentContext,框架将会为你填充它.
举例来说,下面是一个Component如何为上面声明的ColorChangedEvent定义一个handler.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @LayoutSpec class MyComponentSpec { @OnCreateLayout static ComponentLayout onCreateLayout( LayoutContext c, @Prop String someColor) { return Column.create(c) ... .child( ColorComponent.create(c) .color(someColor) .colorChangedHandler(MyComponent.onColorChanged(c)) ... .build(); } @OnEvent(ColorChangedEvent.class) static void onColorChanged( ComponentContext c, @FromEvent int color, @Prop String someProp) { Log.d("MyComponent", "Color changed: " + color); } }
|
对一个或者多个回调方法的参数使用@Param注释,你可以定义动态的事件参数.如果你想要定义一个确定类型的事件的回调(例如onAvatarClicked()),但是你也想知道哪一个头像被点击了,使用@Param注释会变得非常实用.这个情况中的avatar参数将会被传递到eventHandler factory方法中.
正如你所见,@OnEvent回调可以访问所有的Component的prop,就像其他的Spec方法一样.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @LayoutSpec class FacePileComponentSpec { @OnCreateLayout static ComponentLayout onCreateLayout( LayoutContext c, @Prop Uri[] faces) { ComponentLayout.Builder builder = Column.create(c); for (Uri face : avatarUrls) { builder.child( FrescoImage.create(c) .uri(face) .withLayout() .clickHandler(FacePileComponent.onFaceClicked(c, face)); } return builder.build(); } @OnEvent(ClickEvent.class) static void onFaceClicked( ComponentContext c, @Param Uri face) { Log.d("FacePileComponent", "Face clicked: " + face); } }
|