ScreenFragment 事件
本节介绍界面 fragment 控制器能处理的生命周期事件。
InitEvent
该事件在 fragment 控制器和其所有以声明方式定义的组件创建之后,并且依赖注入完成才触发。此时,内部的 fragment 还没有初始化。有些可视化组件没有完全初始化,比如按钮还没有连接到操作。如果该 fragment 是通过 XML 的方式绑定到宿主界面的话,该事件会在宿主控制器的 InitEvent
事件之后触发。否则会在该 fragment 被添加到宿主组件树的时候触发。
AfterInitEvent
该事件会在 fragment 控制器和其所有以声明方式定义的组件创建之后,并且依赖注入完成,所有组件内部的初始化过程也已经结束之后触发。此时,内部的界面 fragment(如果有的话)已经触发了它们自己的 InitEvent
和 AfterInitEvent
事件。在该事件的监听器中,可以创建可视化和数据组件,并能执行依赖内部 fragment 初始化完成的额外初始化过程。
AttachEvent
该事件会在 fragment 被添加到宿主的组件树时触发,fragment 已经完全初始化了,InitEvent
和 AfterInitEvent
事件已经触发。在该事件的监听器中,可以通过 getHostScreen()
和 getHostController()
访问宿主界面的界面和方法。
监听 AttachEvent
事件的示例:
@UiController("sample_AddressFragment")
@UiDescriptor("address-fragment.xml")
public class AddressFragment extends ScreenFragment {
private static final Logger log = LoggerFactory.getLogger(AddressFragment.class);
@Subscribe
private void onAttach(AttachEvent event) {
Screen hostScreen = getHostScreen();
FrameOwner hostController = getHostController();
log.info("onAttach to screen {} with controller {}", hostScreen, hostController);
}
监听宿主界面事件
在 fragment 控制器中,可以订阅父界面的事件,需要在注解中为 target
属性指定 PARENT_CONTROLLER
值,示例:
@Subscribe(target = Target.PARENT_CONTROLLER)
private void onBeforeShowHost(Screen.BeforeShowEvent event) {
// ...
}
这个方法可以处理任何事件,包括实体编辑界面发送的 InitEntityEvent 事件。
在宿主界面监听 Fragment 事件
在宿主界面控制器中,可以订阅 fragment 控制器发送的事件。下面示例中,当 fragment 组件更改时发送自定义事件,并在宿主界面处理。
在 fragment 控制器中,创建事件类和一个方法用于注册事件监听器:
public static class CountryChangeEvent extends EventObject { (1)
private Country country;
public CountryChangeEvent(Object source, Country value) {
super(source);
country = value;
}
public Country getCountry() {
return country;
}
}
public Subscription addChangeListener(Consumer<CountryChangeEvent> listener) {
return getEventHub().subscribe(CountryChangeEvent.class, listener); (2)
}
@Subscribe("countryField")
public void onCountryFieldValueChange(HasValue.ValueChangeEvent<Country> event) {
fireEvent(CountryChangeEvent.class, new CountryChangeEvent(this, event.getValue())); (3)
}
1 | 通过继承 EventObject 创建自定义事件类。 |
2 | 创建一个方法用于注册自定义事件监听器。 |
3 | 使用 fireEvent() 方法发送自定义事件。 |
现在可以在宿主控制器中以声明式的方法订阅自定义 fragment 事件:
@Autowired
private Notifications notifications;
@Subscribe(id = "addressFragment", target = Target.CONTROLLER) (1)
protected void onChange(AddressFragment.CountryChangeEvent event) {
notifications.create()
.withCaption("Changed country: " + event.getCountry())
.show();
}
1 | 使用 fragment id 和 Target.CONTROLLER 订阅 fragment 事件。 |