积分143 / 贡献0

提问0答案被采纳0文章10

[经验分享] flutter使用Ohos原生组件的方法

深开鸿_石悌君 显示全部楼层 发表于 2024-10-10 16:51:27
flutter中有些功能使用原生组件包装会更简单,本文以flutter\_filereader的实现过程为例说明Ohos中使用原生组件的实现方法。

filereader插件的作用是显示本地文件,在安卓和iOS上都使用系统webview实现,所以在Ohos上也采用了同样的思路。鸿蒙化主要的增量修改点如下

### 自定义Component和PlatformView

实现关键点:

1、使用AppStorage交换Component和PlatformView之间的数据

2、使用@Watch装饰器监听数据变化

#### 使用原生组件自定义Component

```typescript
AppStorage.setOrCreate('url', '')

@Component
struct FileReaderComponent {
  @Prop params: Params
  filereaderView: FileReaderView = this.params.platformView as FileReaderView
  @StorageLink('url') @Watch('onOpenFile') url: string = ''

  controller: webview.WebviewController = new webview.WebviewController();
  build() {
    Column() {
      Web({ src: this.url, controller: this.controller, incognitoMode: true })
        .fileAccess(true)
    }
  }

  onOpenFile(propName: string): void {
    Log.d(TAG, "onOpenFileUrl:" + this.url)
    this.controller.loadUrl(this.url)
  }
}

@Builder
function FileReaderBuilder(params: Params) {
  FileReaderComponent({ params: params })
}
```

#### 实现自定义PlatformView

```typescript
@Observed
export class FileReaderView extends PlatformView implements MethodCallHandler {
  methodChannel: MethodChannel;

  constructor(context: common.Context, viewId: number, args: ESObject, message: BinaryMessenger) {
    super();
    // 注册消息通道
    this.methodChannel = new MethodChannel(message, `wv.io/FileReader_${viewId}`, StandardMethodCodec.INSTANCE);
    this.methodChannel.setMethodCallHandler(this);
  }
  
  onMethodCall(call: MethodCall, result: MethodResult): void {
    // 接受Dart侧发来的消息
    let method: string = call.method;
    Log.d(TAG, "method=" + method)
    switch (method) {
      case 'openFile':
        let path = call.args as string
        let link1: SubscribedAbstractProperty<string> = AppStorage.link('url');
        link1.set("file://" + path)
        result.success(true);
        break;
    }
  }
  
  getView(): WrappedBuilder<[Params]> {
    return new WrappedBuilder(FileReaderBuilder);
  }

  dispose(): void {
  }
}
```

### 实现自定义的PlatformViewFactory并注册

#### 实现自定义的PlatformViewFactory

```dart
export class FileReaderFactory extends PlatformViewFactory {
  message: BinaryMessenger;

  constructor(message: BinaryMessenger, createArgsCodes: MessageCodec<Object>) {
    super(createArgsCodes);
    this.message = message;
  }

  public create(context: common.Context, viewId: number, args: Object): PlatformView {
    return new FileReaderView(context, viewId, args, this.message);
  }
}
```

代码基本都差不多,修改类名就可以

#### 注册自定义PlatformViewFactory

在插件的onAttachedToEngine注册自定义PlatformViewFactory

```typescript
onAttachedToEngine(binding: FlutterPluginBinding): void {
    Log.d("FileReaderView", "onAttachedToEngine")

    this.methodChannel = new MethodChannel(binding.getBinaryMessenger(), "wv.io/FileReader");
    this.methodChannel.setMethodCallHandler(this);

    binding.getPlatformViewRegistry()?.
    registerViewFactory('FileReader', new FileReaderFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE));
  }
```

### 在dart侧中增加Ohos平台View创建

```dart
Widget _createOhosView() {
    return OhosView(
      viewType: "FileReader",
      onPlatformViewCreated: _onPlatformViewCreated,
      creationParamsCodec: StandardMessageCodec(),
    );
  }
```

上述函数一般在flutter控件类的build函数中调用

### 参考资料

[flutter_filereader鸿蒙化代码](https://gitee.com/openharmony-sig/fluttertpc_flutter_filereader)

[如何使用PlatformView](https://gitee.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/04_development/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8PlatformView.md)



©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部