在 Kanzi Android framework (droidfw) 中观察状态变化和处理事件。¶
观察状态更改¶
您可以实现 KanziViewListener 来监听 KanziView 中的状态变化。使用此方法注入自定义初始化和反初始化逻辑。
例如:
使用
KanziViewListener.onAttachedToWindow回调来访问域,注册 Kanzi Engine Java 插件或手动设置视图的节点树。view.addListener(new KanziViewListener() { ... @Override public void onAttachedToWindow(View view, Domain domain) { // Register a plugin. domain.registerPlugin(new MyPlugin()); // Manually setup the node tree. // Instantiate a node. ObjectRef<TextBlock2D> text = TextBlock2D.create(domain, "text"); // Set as root of the view. ((KanziView) view).setRoot(text.get()); // Set properties on a node. text.get().setProperty(TextBox2D.TextProperty, "Hello Kanzi!");
view.addListener(object : KanziViewListener { ... override fun onAttachedToWindow(view: View, domain: Domain) { // Register a plugin. domain.registerPlugin(MyPlugin()) // Manually setup the node tree. // Instantiate a node. val text = TextBlock2D.create(domain, "text") // Set as root of the view. (view as KanziView).root = text.get() // Set properties on a node. text.get().setProperty(TextBox2D.TextProperty, "Hello Kanzi!")
使用
KanziViewListener.onStartupPrefabLoaded回调来访问和修改您配置的启动预设实例化的节点树。view.addListener(new KanziViewListener() { ... @Override public void onStartupPrefabLoaded(View view, Domain domain) { // Look up a child node starting from the root. TextBox2D text = ((KanziView)view).getRoot().lookupNode("#Text"); // Set properties on a node. text.setProperty(TextBox2D.TextProperty, "Hello world!");
view.addListener(object : KanziViewListener { ... override fun onStartupPrefabLoaded(view: View, domain: Domain) { // Look up a child node starting from the root. val text = (view as KanziView).root.lookupNode<TextBox2D>("#Text") // Set properties on a node. text.setProperty(TextBox2D.TextProperty, "Hello world!")
要了解有关 Kanzi Engine Java 插件的更多信息,请参阅 创建 Kanzi Engine Java 插件。
处理输入¶
默认情况下,KanziSurfaceView 和 KanziTextureView 处理输入事件。如果您希望 Kanzi Engine 处理使用 KanziViewAdapter 的任意视图的事件,则必须手动转发此类输入事件。为此,请使用这些接口:
默认情况下,所有 Kanzi 视图将 focusableInTouchMode 设置为 True,除非通过编程或布局属性另行设置。这使得它们在被点击时获得并保持焦点。请参阅 Android touch mode。
处理来自 Android Automotive 旋转控制器的输入¶
默认情况下,KanziSurfaceView 和 KanziTextureView 处理旋转控制器输入。
旋转操作 |
Kanzi 如何处理这些操作 |
|
|---|---|---|
|
|
Kanzi Android framework (droidfw) 将这些操作处理为相应的箭头键事件。 Kanzi 不支持并忽略来自对角微调的输入。 |
|
居中按钮 |
Kanzi Android framework (droidfw) 尝试为聚焦的 Kanzi 视图启用直接操作模式。如果 Kanzi Android framework (droidfw) 无法启用直接操作模式,它会将按键事件转发给 Kanzi Engine。Kanzi Engine 将旋转中心按钮的按键代码 |
|
上一步按钮 (Back button) |
Kanzi Android framework (droidfw) 将键事件转发到 Kanzi Engine。如果 Kanzi Engine 不消费该事件,Kanzi Android framework (droidfw) 将禁用 Kanzi 视图的直接操作模式。 |
|
|
Android 发送一个通用运动事件,其中包含旋转方向和按压次数。 Kanzi 视图将所有通用运动事件转发到
|
要禁用默认的旋转控制器输入处理,使用以下方法之一:
在布局文件中,为 Kanzi 视图元素,将
rotaryHandlingEnabled属性设置为false:<com.rightware.kanzi.KanziSurfaceView android:id="@+id/rotaryview" app:name="Rotary" app:kzbPathList="rotary.kzb" app:startupPrefabUrl="kzb://rotary/StartupPrefab" app:rotaryHandlingEnabled="false"/>
在活动代码中,将
false传递给KanziViewAdapter.setRotaryHandlingEnabled函数调用:protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.activity_main); mView = findViewById(R.id.rotaryview); mView.getAdapter().setRotaryHandlingEnabled(false); }
处理方向更改¶
当屏幕方向发生变化时,Android 应用程序默认情况下会销毁并重新创建活动。这允许应用程序为纵向和横向屏幕使用备用布局,但这也意味着您会丢失所有内部 Kanzi 状态。
您可以通过在 AndroidManifest.xml 文件中添加 android:configChanges="orientation" 属性来覆盖此设置。使用此选项,活动在方向更改时不再被销毁,而是在活动上调用 onConfigurationChanged()。手动将此事件转发到 KanziView.handleOrientationChange。此选项避免重新创建 Kanzi 控件,因此保留了所有内部状态。请参阅 Android 配置更改。
处理 Android 生命周期¶
虽然 KanziSurfaceView 和 KanziTextureView 默认情况下处理窗口和表面事件,但使用 KanziViewAdapter 的任意视图必须通过 KanziViewAdapter.handleAttachedToWindow、KanziViewAdapter.handleSurfaceCreated、KanziViewAdapter.handleSurfaceChanged、KanziViewAdapter.handleSurfaceDestroyed 和 KanziViewAdapter.handleDetachedFromWindow 接口手动转发它希望 Kanzi 处理的窗口和表面事件。
处理视图的用户可见性¶
Kanzi Android framework (droidfw) 会自动持续跟踪每个已连接的视图对用户是否可见,并停止隐藏视图的 rendering 和输入处理。
要检查视图是否对用户可见,Kanzi Android framework (droidfw) 考虑:
视图的可见性状态
视图的所有祖先的可见性状态
视图的 alpha 值
通过
View.getGlobalVisibleRect()计算的视图的有效可见部分。
使用 KanziViewAdapter 的任意视图必须手动转发可见性事件,以便通过 KanziViewAdapter.handleVisibilityChange 接口处理 Kanzi。
空闲状态¶
Kanzi Android framework (droidfw) 会在没有工作时自动暂停不必要的操作,并在有工作时唤醒。请参阅 应用程序空闲状态。
为了在暂停期间检测来自 Kanzi 主循环外部的更改,Kanzi Android framework (droidfw) 可以:
订阅 Android
MessageQueue.IdleHandler事件。在 Android Choreographer 上运行轻量级任务。
默认情况下,Kanzi Android framework (droidfw) 订阅 Android 空闲事件,并在 Android 应用程序进入空闲状态时检查外部更改。在此模式下,Kanzi 在暂停期间的 CPU 使用率真正降为零。
您可以通过调用 KanziRuntime.enableSuspendedChangeTrackingTask 将 Kanzi 切换为使用后台任务。在此模式下,Kanzi 以通过 KanziRuntime.setSuspendedChangeCheckRate 设置的频率在 Android Choreographer 上运行轻量级任务。通过更改此频率,您可以控制 Kanzi 检查外部更改的频率。默认值为 0 时,Kanzi 以显示器 vsync 频率跟踪外部更改。您可以进一步降低此频率及相关的 CPU 消耗,但代价是在有工作时唤醒会延迟。此频率独立于 rendering 和动画的频率,后两者由帧率限制控制。