介绍
为了便于大家在使用本案例集时能够更详细的了解各个案例,本案例基于Web预渲染实现了案例介绍功能,即应用右下角的问号icon。
效果图预览
使用说明
- 因为直接加载的线上README,因此本功能需联网使用
- 点击icon,即会弹出对应案例的README
- 按钮可拖动
- 返回或下拉bindSheet上方的dragBar可隐藏帮助页
案例适配说明
为确保案例正确显示其README,请确保entry模块的依赖中@ohos/xxx中的xxx与案例目录名相同
实现思路
- 使用Stack承载Navigation,从而使得icon能够在应用的各个案例(NavDestination承载)上显示。
Stack() {
Navigation(this.pageStack) {
//...
}
// 帮助功能:在每个案例的右下角添加“帮助”功能
HelperView()
}
2.使用BindSheet+WebView加载仓上各模块README。
build() {
Image($r("app.media.help"))
.bindSheet($$this.isShowReadMe, this.buildReadMeSheet(), {
//...
})
}
@Builder
buildReadMeSheet(): void {
//...
}
3.使用webview预渲染提升用户体验,复用webview实例减少资源占用。
@Builder
function WebBuilder(data: Data) {
Web({ src: data.url, controller: data.controller })
.onPageBegin(() => {
data.controller.onActive();
})
}
const wrap: WrappedBuilder<Data[]> = wrapBuilder<Data[]>(WebBuilder);
export class NWebNodeController extends NodeController {
private rootNode: BuilderNode<Data[]> | null = null;
makeNode(uiContext: UIContext): FrameNode | null {
if (this.rootNode) {
return this.rootNode.getFrameNode();
}
return null; // 返回null控制动态组件脱离绑定节点
}
initWeb(url: string, uiContext: UIContext, controller: WebviewController) {
if (this.rootNode) {
return;
}
this.rootNode = new BuilderNode(uiContext);
this.rootNode.build(wrap, { url: url, controller: controller });
}
}
interface CurrentNode {
url: string | null;
webController: webview.WebviewController | null;
nWebController: NWebNodeController | null;
}
/**
* 复用webview
*/
function loadUrl(url: string): void {
if (currentNode.webController) {
currentNode.url = url;
currentNode.webController.loadUrl(url);
}
}
const currentNode: CurrentNode = { url: null, nWebController: null, webController: null };
/**
* 创建web实例,如果已经存在web实例,复用
* @param url
* @param uiContext
*/
export function createNWeb(url: string, uiContext: UIContext): void {
if (currentNode.webController && currentNode.nWebController && currentNode.url !== url) {
loadUrl(url);
return;
}
clearHelperWeb();
let baseNode = new NWebNodeController();
let controller = new webview.WebviewController();
// 初始化自定义web组件
baseNode.initWeb(url, uiContext, controller);
currentNode.url = url;
currentNode.webController = controller;
currentNode.nWebController = baseNode;
}
/**
* 获取NodeController
*/
export function getNWeb(url: string, uiContext: UIContext): NWebNodeController | null {
if (currentNode.url != url) {
loadUrl(url);
}
return currentNode.nWebController;
}
/**
* 停止页面加载:当url频繁切换时使用
*/
export function stopWebLoad(): void {
if (currentNode.url && currentNode.webController) {
currentNode.webController.stop();
}
}
4.监听NavPathStack的变更,及时切换url
onPageStackChange(): void {
if (!this.pageStack.size()) {
this.helperUrl = HelperConstants.HELPER_URL_HOME;
} else {
const size: number = this.pageStack.size();
let moduleName: string = this.pageStack.getAllPathName()[size-1].split('/')[1];
this.helperUrl = HelperConstants.HELPER_URL_PROTOTYPE.replace("{placeholder}", moduleName);
}
}