1. 插件介绍

Flutter Plugin 示例展示了如何在现有鸿蒙应用中嵌入使用插件的全屏 Flutter 实例。该示例包含了在 Flutter 引擎创建时初始化插件所需的原生代码,并演示了如何在 Flutter 视图中使用多种插件功能。

主要功能:

  • 在现有鸿蒙应用中嵌入全屏 Flutter 实例
  • 演示 Flutter 引擎创建时插件的初始化过程
  • 使用多个 Flutter 插件:url_launcher(浏览器调用)、sensors(传感器)、provider(状态管理)
  • 实现原生平台与 Flutter 模块之间的通信
  • 展示如何在 Flutter 视图中添加按钮打开外部链接

适用场景:

  • 需要在现有鸿蒙应用中集成 Flutter 功能
  • 希望在 Flutter 模块中使用各种插件扩展功能
  • 需要实现原生平台与 Flutter 模块之间的数据通信
  • 学习 Flutter 插件在鸿蒙系统上的使用方法

2. 如何使用插件

2.1 包的引入

在项目的 pubspec.yaml 文件中,添加以下依赖配置:

dependencies:
  flutter_module_using_plugin:
    git:
      url: "https://atomgit.com/flutter/samples.git"
      path: "add_to_app/plugin/flutter_module_using_plugin"
  
  # 如果需要单独使用这些插件
  provider:
    git:
      url: "https://atomgit.com/flutter/plugins.git"
      path: "packages/provider/provider"
  
  url_launcher:
    git:
      url: "https://atomgit.com/openharmony-tpc/flutter_packages.git"
      path: "packages/url_launcher/url_launcher"
  
  sensors:
    git:
      url: "https://atomgit.com/flutter/plugins.git"
      path: "packages/sensors/sensors"

然后运行 flutter pub get 命令获取依赖:

flutter pub get

2.2 初始化 Flutter 引擎和插件

在鸿蒙应用的入口类中,初始化 Flutter 引擎并注册插件:

import { FlutterEngine, FlutterView } from '@flutter/platform_ohos';
import { GeneratedPluginRegistrant } from './plugin/GeneratedPluginRegistrant';

class EntryAbility extends Ability {
  private flutterEngine: FlutterEngine;
  
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    super.onCreate(want, launchParam);
    
    // 初始化 Flutter 引擎
    this.flutterEngine = new FlutterEngine(this.context);
    
    // 注册插件
    GeneratedPluginRegistrant.registerWith(this.flutterEngine);
    
    // 运行 Flutter 引擎
    this.flutterEngine.run();
    
    // 其他初始化代码...
  }
  
  // 其他方法...
}

2.3 嵌入 Flutter 视图

在鸿蒙页面中嵌入 Flutter 视图:

import { FlutterView } from '@flutter/platform_ohos';

class Index extends AbilitySlice {
  private componentContainer: ComponentContainer;
  
  onStart(): void {
    super.onStart();
    
    // 创建 Flutter 视图
    const flutterView = new FlutterView(this);
    flutterView.setSize(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
    
    // 附加到 Flutter 引擎
    flutterView.attachToEngine(entryAbility.flutterEngine);
    
    // 设置页面内容
    this.componentContainer = this.findComponentById('component-container') as ComponentContainer;
    this.componentContainer.addComponent(flutterView);
  }
  
  // 其他方法...
}

2.4 API 调用

2.4.1 使用 MethodChannel 进行通信
// Flutter 端代码
class CounterModel extends ChangeNotifier {
  CounterModel() {
    _channel.setMethodCallHandler(_handleMessage);
    _channel.invokeMethod<void>('requestCounter');
  }

  final _channel = const MethodChannel('dev.flutter.example/counter');

  int _count = 0;

  int get count => _count;

  void increment() {
    _channel.invokeMethod<void>('incrementCounter');
  }

  Future<dynamic> _handleMessage(MethodCall call) async {
    if (call.method == 'reportCounter') {
      _count = call.arguments as int;
      notifyListeners();
    }
  }
}
// 鸿蒙端代码
import { MethodChannel } from '@flutter/platform_ohos';

// 创建 MethodChannel
const channel = new MethodChannel(flutterEngine.dartExecutor.binaryMessenger, 'dev.flutter.example/counter');

// 设置 MethodCallHandler
channel.setMethodCallHandler((call, result) => {
  if (call.method === 'requestCounter') {
    // 返回当前计数器值
    result.success(this.counterValue);
  } else if (call.method === 'incrementCounter') {
    // 增加计数器值
    this.counterValue++;
    // 通知所有 Flutter 实例
    channel.invokeMethod('reportCounter', this.counterValue);
    result.success(null);
  }
});
2.4.2 使用 url_launcher 插件
import 'package:url_launcher/url_launcher.dart' as launcher;

ElevatedButton(
  onPressed: () async {
    // 使用 url_launcher 插件打开 Flutter 文档
    final url = Uri.parse('https://flutter.dev/docs');
    if (await launcher.canLaunchUrl(url)) {
      await launcher.launchUrl(url);
    }
  },
  child: const Text('Open Flutter Docs'),
),
2.4.3 使用 provider 进行状态管理
// 初始化应用
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  final model = CounterModel();
  
  runApp(
    ChangeNotifierProvider.value(
      value: model,
      child: const MyApp(),
    ),
  );
}

// 使用状态
Consumer<CounterModel>(
  builder: (context, model, child) {
    return Text(
      'Taps: ${model.count}',
      style: Theme.of(context).textTheme.headlineSmall,
    );
  },
),

2.5 注册插件

在鸿蒙应用中,需要为每个使用的插件进行注册。通常,这会在 GeneratedPluginRegistrant.ets 文件中自动生成:

// GeneratedPluginRegistrant.ets
import { FlutterEngine } from '@flutter/platform_ohos';
import { UrlLauncherPlugin } from 'url_launcher';
import { SensorsPlugin } from 'sensors';

export function registerWith(flutterEngine: FlutterEngine): void {
  // 注册 url_launcher 插件
  UrlLauncherPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger);
  
  // 注册 sensors 插件
  SensorsPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger);
  
  // 注册其他插件...
}

3. 多视图集成

该示例还支持多视图集成场景,提供了一个备用入口点:

/// 这是此模块的备用入口点,用于在(多)视图集成场景中显示 Flutter UI
void showCell() {
  runApp(const Cell());
}

在鸿蒙应用中,可以通过以下方式调用这个入口点:

// 创建 Flutter 引擎并指定入口点
const flutterEngine = new FlutterEngine(this.context, {
  entrypoint: 'showCell'
});

// 运行 Flutter 引擎
flutterEngine.run();

4. 总结

Flutter Plugin 示例展示了如何在鸿蒙应用中嵌入使用插件的 Flutter 实例,包括插件的初始化、注册和使用。该示例使用了多个常用插件,演示了 Flutter 与原生平台之间的通信机制。

通过本指南,您已经了解了如何:

  1. 引入 Flutter Plugin 模块和相关依赖
  2. 初始化 Flutter 引擎并注册插件
  3. 在鸿蒙页面中嵌入 Flutter 视图
  4. 使用 MethodChannel 实现原生平台与 Flutter 之间的通信
  5. 使用 url_launcher、sensors 和 provider 等插件
  6. 实现多视图集成场景

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐