HarmonyOS鸿蒙Next原生应用如何将flutter的页面嵌入到TabContent中

HarmonyOS鸿蒙Next原生应用如何将flutter的页面嵌入到TabContent中 应用是原生开发的,首页的五个tab,其中一个需要替换成flutter页面,(不是跳转flutter页面)如何实现?

5 回复

【背景知识】

FlutterBoost插件为现有HarmonyOS应用程序提供Flutter混合集成方案:

  • FlutterBoost可将Flutter作为Webview那样来使用,同时管理Native页面和Flutter页面;
  • FlutterBoost可处理页面映射和跳转,开发者只需关心页面的名字和参数即可。

【解决方案】

构造FlutterUIComponent组件,在TabContent中加FlutterUIComponent组件实现将Flutter页面作为HarmonyOS工程的tab页,具体参考代码如下:

build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
        TabContent() {
          Row() {
            Column() {
              Button('打开Flutter页面')
                .margin({ bottom: 10 })
                .onClick(() => {
                  try {
                    FlutterBoost.getInstance().open('flutterPage', {})
                  } catch (err) {
                    hilog.info(0x0000, TAG, '%{public}s', 'Failed to 打开Flutter页面');
                  }
                })
              Button('打开Native页面')
                .margin({ bottom: 10 })
                .onClick(() => {
                  try {
                    router.pushUrl({ url: 'pages/NativePage' })
                  } catch (err) {
                    hilog.info(0x0000, TAG, '%{public}s', 'Failed to 打开Native页面');
                  }
                })
            }
            .width('100%')
          }
          .height('100%')
        }.tabBar(this.tabBuilder(0, '首页'))

        TabContent() {
          FlutterUIComponent({ uri: 'flutterPage' })
        }.tabBar(this.tabBuilder(0, 'flutterPage'))
      }
      .vertical(false)
      .barMode(BarMode.Fixed)
      .barWidth(360)
      .barHeight(56)
      .animationDuration(400)
      .onChange((index: number) => {
        this.currentIndex = index
      })
      .width('100%')
      .height('100%')
    }.width('100%')
  }
  1. 构造uri和params参数,其中uri为Flutter页面对应的名字,params为入参,当点击对应的tab时,可跳转到uri对应的Flutter页面(同时保留tabbar),具体参考代码如下:
@Component
export struct FlutterUIComponent {
  @Prop uri: string;
  @Prop params: Record<string, Object>;

  private flutterEntry: FlutterBoostEntry | null = null;
  private flutterView?: FlutterView;
  private effect: object =
    TransitionEffect.OPACITY
      .combine(TransitionEffect.move(TransitionEdge.END)).animation({curve: curves.springMotion()});

  aboutToAppear() {
    this.flutterEntry = new FlutterBoostEntry(getContext(this), {
      uri: this.uri,
      params: this.params,
    });
    this.flutterEntry.aboutToAppear();
    this.flutterView = this.flutterEntry.getFlutterView();
    hilog.info(0x0000, TAG, 'Component(#%{public}s) aboutToAppear===', this.uri);
  }

  aboutToDisappear() {
    hilog.info(0x0000, TAG, 'Component(#%{public}s) aboutToDisappear===', this.uri);
    this.flutterEntry?.aboutToDisappear()
  }

  onPageShow() {
    hilog.info(0x0000, TAG, 'Component(#%{public}s) onPageShow===', this.uri);
    this.flutterEntry?.onPageShow()
  }
  // 1
  onPageHide() {
    hilog.info(0x0000, TAG, 'Component(#%{public}s) onPageHide===', this.uri);
    this.flutterEntry?.onPageHide()
  }

  build() {
    Stack() {
      FlutterPage({ viewId: this.flutterView?.getId() })
    }
    .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => {
      if (isVisible) {
        setTimeout(() => {
          this.onPageShow();
        }, 0);
      } else {
        this.onPageHide();
      }
    })
    .transition(this.effect)
  }
}

更多关于HarmonyOS鸿蒙Next原生应用如何将flutter的页面嵌入到TabContent中的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


虽然我已经解决,不过你的答案也跟我写的差不多,

还没做过相关开发,顶贴

在HarmonyOS Next中,可通过Flutter侧创建MethodChannel,在ArkUI侧使用TabContent和Tabs组件实现页面嵌入。在Flutter端封装页面为独立Widget,通过MethodChannel传递渲染指令到ArkUI端。ArkUI端在TabContent的builder回调中创建FlutterViewController,加载对应的Flutter页面路由。需确保Flutter引擎已初始化,并在应用配置中声明Flutter能力。页面通信通过Platform Channel完成数据交互。

在HarmonyOS Next中,可以通过ArkUI的Web组件或XComponent结合FFI(Foreign Function Interface)实现Flutter页面的嵌入。具体步骤:

  1. 构建Flutter模块:将目标页面打包为独立Flutter模块,编译为动态库(如.so文件)或Web资源(若使用Web渲染)。

  2. 原生集成

    • 方案一(Web渲染):若Flutter页面支持Web,可将Flutter编译为Web资源,通过Web组件在TabContent中加载URL。
    Web({ src: 'flutter_page_url' })
    
    • 方案二(原生渲染):通过FFI调用Flutter引擎的C/C++ API,利用XComponent渲染Flutter视图。需在Native层初始化Flutter引擎,并将Surface句柄传递给Flutter渲染层。
  3. 通信机制:通过Web组件的JavaScript桥接或FFI通道实现ArkUI与Flutter页面的双向数据交互。

注意事项:

  • Flutter模块需适配HarmonyOS的架构(如ARM64)。
  • 性能敏感场景建议优先测试渲染兼容性。
  • 目前HarmonyOS对Flutter的原生支持仍在演进,需关注官方更新。
回到顶部