Facebook出品的Android声明式开源新框架Litho文档翻译-事件处理概述

欢迎转载,转载请标明出处.
英文原文文档地址: 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);
}
}




回到导航页