介绍
为了便于大家在使用本案例集时能够更详细的了解各个案例,本案例基于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);
  }
}









