本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
WebContainer
WebContainer 是一个在你的 CrossFly UI 内嵌入原生 webview(HTML/JavaScript 内容)的小部件。它是一个轻薄的包装器:自身不绘制任何内容 —— 一切都委托给平台通过 PlatformUtils.instance.createWebView() 提供的 IWebView。它用于像普通屏幕组件一样显示一个页面、一个 HTML 表单或一个 web 面板。
⚠️ 关于可用性的坦诚说明:
WebContainer仅在存在原生IWebView的平台上有效(Android、iOS、桌面)。本代码库以及 Web/TeaVM 目标中都没有IWebView的具体实现 ——createWebView()在不支持的平台上返回null,此时WebContainer的构造函数会抛出UnsupportedOperationException。在 Web/WebGL 构建中,请优先使用打开外部页面(view(url))而不是嵌入 webview。
🔴 · 包:
dev.crossfly.ui· 继承:Component(实现Runnable)· 委托给:IWebView
何时使用
- 在具有原生 webview 的平台上(Android/iOS/桌面),在应用内显示 web 内容(HTML/JS)。
- 集成一个 HTML 表单并通过
setFormSubmitListener捕获提交。
何时不要使用
- 对于简单的静态内容(文本/图像)→ 使用原生小部件(
chartview、标签、图像),而不是加载一个页面。
外观
WebContainer 不绘制自身的像素:系统的原生 webview 覆盖在组件区域之上。可见性在 onPaint 中自动协调 —— webview 仅在父窗口位于最上层(isTopMost())时出现,否则消失。
完整示例(复制、粘贴并运行)
WebContainer 仅在存在原生 IWebView 的平台上有效。此示例在创建容器之前通过 PlatformUtils.instance.createWebView() != null 检测支持情况(避免构造函数抛出 UnsupportedOperationException),并在不支持时(例如 Web/TeaVM 目标)降级为使用 view(url) 在外部打开页面。
package com.exemplo;
import dev.crossfly.PlatformUtils;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
String url = "https://example.com";
// 仅当平台提供原生 IWebView 时才创建 WebContainer。
if (PlatformUtils.instance.createWebView() != null)
{
WebContainer browser = new WebContainer();
browser.show(url);
add(LAY_FILL, browser);
}
else
{
// Web/TeaVM 目标(无内置 webview):在外部打开页面。
add(LAY_AUTO, new Label("Sem webview nativa — abrindo externamente…"));
PlatformUtils.instance.view(url);
}
}
}
下面的片段仅展示核心部分(放入
onShow()内的内容)。要运行它们,请将其放入上面的MainWindow骨架中。
基本用法
WebContainer browser = new WebContainer(); // 可能抛出 UnsupportedOperationException
browser.show("https://example.com");
container.add(LAY_FILL, browser);
构造函数
| 构造函数 | 描述 |
|---|---|
WebContainer() |
通过 PlatformUtils.instance.createWebView() 获取原生 webview 并以不可见状态启动。如果平台不提供 IWebView,则抛出 UnsupportedOperationException。 |
属性与自定义
| 方法 | 类型 | 作用 |
|---|---|---|
show(String url) |
void |
在 webview 中加载并显示该 URL。 |
hide() |
void |
隐藏 webview 同时保留页面状态。 |
setVisible(boolean) |
void |
true = show(null)(保留当前 URL/状态);false = hide()。 |
isVisible() |
boolean |
webview 是否可见。 |
evaluateJavaScript(String script) |
void |
在页面上执行 JavaScript。 |
setFormSubmitListener(IWebView.FormSubmitListener) |
void |
注册用于捕获 HTML 表单提交的回调。 |
IWebView要求操作发生在渲染线程(paint 线程)上。如果你从其他线程调用show/evaluateJavaScript,请用Component.onUI(...)返回该线程。
回调与事件
| 回调 | 触发时机 |
|---|---|
IWebView.FormSubmitListener(通过 setFormSubmitListener) |
在嵌入的页面内提交 HTML 表单时。 |
WebContainer不使用onAction/onClick—— 交互发生在 web 页面内部。唯一的应用钩子是表单提交监听器。
状态
- 可见 / 隐藏:由
show/hide/setVisible管理,并由窗口位置自动管理(当父窗口不在最上层时 webview 消失)。 - 已移除:在
onRemove中,调用view.removeView(),且IWebView无法被复用 —— 要重新显示,请创建一个新的WebContainer。
带提交捕获的 HTML 表单(具备 webview 的平台)
WebContainer form = new WebContainer();
form.setFormSubmitListener(dados -> processarEnvio(dados)); // IWebView.FormSubmitListener
form.show("https://meuservico/formulario.html");
container.add(LAY_FILL, form);
在 Web 目标上的安全降级
// 在 Web/TeaVM 构建中,createWebView() 返回 null,构造函数抛出异常。
try {
WebContainer c = new WebContainer();
c.show("https://example.com");
container.add(LAY_FILL, c);
} catch (UnsupportedOperationException e) {
// 无内置 webview:在外部打开页面。
PlatformUtils.instance.view("https://example.com");
}
最佳实践
- 将创建过程封装在
UnsupportedOperationException的try/catch中,以在 Web 目标上良好降级。
常见错误
- 在不支持的平台上创建
WebContainer:抛出UnsupportedOperationException。请事先处理或检测。 - 在
onRemove之后复用:IWebView已被丢弃(removeView());请创建一个新实例。 - 期望在 Web/TeaVM 目标上嵌入 web:没有实现;嵌入 webview ≠ 成为一个 web 应用。请使用
view(url)。
另请参阅
- 领域指南:
ui/· 食谱:cookbook/ - 概念(平台、UI 线程):
concepts/ - 相关组件:
locationview