HarmonyOS next之PlatformView同层渲染方案适配切换指导
PlatformView旧方案
简述
在Flutter适配层定义DynamicView和DVModel
@Observed
export class DVModel {
id_: number;
compType: string;
params: DVModelParameters;
events: DVModelEvents;
children: DVModelChildren;
builder: Any;
public getLayoutParams(): DVModelParameters {
return this.params;
}
}
@Component
export struct DynamicView{
@ObjectLink model:DVModel;
@ObjectLink children:DVModelChildren;
@ObjectLink params:DVModelParameters;
@ObjectLink events:DVModelEvents;
@BuilderParam customBuilder?:($$:BuilderParams)=>void;
}
开发者使用json字符串来定义生成DVModel模型,实现PlatformView的定义,将FlutterView置于底层,DynamicView实现的PlatformView置于顶层,DynamicView使用ArkUI实现,所以是通过鸿蒙的原生渲染的。
build() {
Stack() {
XComponent({ id: this.viewId, type: this.xComponentType, libraryname: 'flutter' })
.focusable(true)
.focusOnTouch(true)
.onLoad((context) => {
this.flutterView?.onSurfaceCreated()
Log.d(TAG, "XComponent onLoad ");
})
.onDestroy(() => {
Log.d(TAG, "XComponent onDestroy ");
this.flutterView?.onSurfaceDestroyed()
})
.backgroundColor(Color.Transparent)
ForEach(this.rootDvModel!!, (child: Any) => {
DynamicView({
model: child as DVModel,
params: child.params,
events: child.events,
children: child.children,
customBuilder: child.builder
})
})
}
Flutter页面嵌入PlatformView时会有下面两个严重缺陷:
1. PlatformView覆盖在FlutterView上面出现遮挡问题
2. 页面切换时,FlutterView和PlatformView动画不一致
PlatformView新方案
简述
采用NodeContainer同层渲染功能,将原生平台组件的纹理导出注册到Flutter Engine,由Flutter统一渲染。可以解决旧方案的固有缺陷,并且PlatformView使用自定义ArkUI的Component组件,符合鸿蒙原生应用开发习惯,不用按照DVModel来定义,同时避免写json没有代码提示的困扰。
build() {
Stack() {
NodeContainer(this.nodeController)
.width(this.storageLinkWidth)
.height(this.storageLinkHeight)
XComponent({ id: this.viewId, type: this.xComponentType, libraryname: 'flutter' })
.focusable(true)
.focusOnTouch(true)
.onLoad((context) => {
this.flutterView?.onSurfaceCreated()
Log.d(TAG, "XComponent onLoad ");
})
.onDestroy(() => {
Log.d(TAG, "XComponent onDestroy ");
this.flutterView?.onSurfaceDestroyed()
})
.backgroundColor(Color.Transparent)
}
}
新旧方案实现关键区别:
旧方案:
private model: DVModel = createDVModelFromJson(
{
compType: "Column",
attributes: { height: '200%'},
children: [
{
compType: "Text",
attributes: { value: "Native:发送数据给Dart111111111111111", fontColor: Color.Orange,backgroundColor: Color.Black,height: 100},
events: { onClick: this.sendMessage },
},
{
compType: "Text",
attributes: { value: "Native:来自Dart的数据", marginTop: 20 },
}
],
}
);
/// 自定义PlatformView实体类的实现的接口
getView(): DVModel {
return this.model;
}
新方案:
@Component
struct ButtonComponent {
@Prop params: Params
customView: CustomView = this.params.platformView as CustomView
@StorageLink('numValue') storageLink: string = "first"
@State bkColor: Color = Color.Red
build() {
Column() {
Button("发送数据给Flutter")
.border({ width: 2, color: Color.Blue})
.backgroundColor(this.bkColor)
.onTouch((event: TouchEvent) => {
console.log("nodeController button on touched")
})
.onClick((event: ClickEvent) => {
this.customView.sendMessage();
console.log("nodeController button on click")
})
Text(`来自Flutter的数据 : ${this.storageLink}`)
.onTouch((event: TouchEvent) => {
console.log("nodeController text on touched")
})
}.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.direction(Direction.Ltr)
.width('100%')
.height('100%')
}
}
/// 自定义PlatformView实体类的实现的接口
getView(): WrappedBuilder<[Params]> {
return new WrappedBuilder(ButtonBuilder);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。