Flutter扩展平台视图插件extended_platform_view的使用

Flutter扩展平台视图插件extended_platform_view的使用

ExtendedPlatformView 插件简化了在 Flutter 中初始化和通信平台视图(PlatformView)的过程。它提供了以下功能:

  • 使用单个 ExtendedPlatformView 小部件在 Android 和 iOS 上创建 PlatformView
  • 支持 MethodChannel
  • 在 Android 上切换 HybridCompositionVirtualDisplay

如何使用

创建一个 ExtendedPlatformView 小部件
Widget build(BuildContext context) {
  return ExtendedPlatformView(
    config: const ExtendedPlatformViewConfig(
      viewType: 'sample_platform_view',
      creationParams: "text",
    ),
  );
}
添加 PlatformView 类并在 Android 上注册 viewType
  1. 添加一个继承自 ExtendedPlatformViewPlatformView 类。
class SamplePlatformView: ExtendedPlatformView() {
    override fun initialize(params: CreationParams): View {
        return TextView(context).apply {
            text = params.args as String
        }
    }
}
  1. FlutterActivity 中注册 PlatformView
class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        flutterEngine.extendedPlatformView.register("sample_platform_view") { SamplePlatformView() }
    }
}
添加 PlatformView 类并在 iOS 上注册 viewType
  1. 添加一个继承自 ExtendedPlatformViewPlatformView 类。
import extended_platform_view

class SamplePlatformView: ExtendedPlatformView {
    override func initialize(params: CreationParams) -> UIView {
        let label = UILabel(frame: params.frame)
        label.text = (params.args as! String)

        return label
    }
}
  1. AppDelegate 中注册 PlatformView
import extended_platform_view

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // You have to register ExtendedPlatformView before calling `GeneratedPluginRegistrant.register(with: self)`
        ExtendedPlatformViewRegistrar.register(viewType: "sample_platform_view", builder: { SamplePlatformView() })
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

MethodChannel

如果传递了 methodChannelDelegate 参数,则会创建一个 MethodChannel

在平台端,ExtendedPlatformView 有一个 methodChannel 属性,并且会在调用 initialize(params: CreationParams) 方法之前自动分配。

Widget build(BuildContext context) {
  return ExtendedPlatformView(
    config: const ExtendedPlatformViewConfig(
      viewType: 'sample_platform_view',
      creationParams: "text",
    ),
    methodChannelDelegate: MethodChannelDelegate(
      onCreate: (methodChannel) {
        // do something...
      },
    ),
  );
}

在 Android 上:

override fun initialize(params: CreationParams): View {
    val textView = TextView(context).apply {
        text = params.args as String
    }
    
    methodChannel.setMethodCallHandler { call, result ->
        // do something...
    }
    
    return textView
}

在 iOS 上:

override func initialize(params: CreationParams) -> UIView {
    let label = UILabel(frame: params.frame)
    label.text = (params.args as! String)
    
    methodChannel.setMethodCallHandler({ call, result in
        // do something...
    })
    
    return label
}

Android Composition Mode

Flutter 在 Android 上有两种 PlatformView 组合模式。

默认情况下,ExtendedPlatformView 将使用 HybridComposition

如果需要使用 VirtualDisplay 模式,可以将 ExtendedPlatformViewConfig.androidCompositionMode 设置为 AndroidCompositionMode.virtualDisplay

ExtendedPlatformViewConfig(
    viewType: 'sample_platform_view',
    androidCompositionMode: AndroidCompositionMode.virtualDisplay,
)

示例代码

以下是完整的示例代码:

import 'package:extended_platform_view/extended_platform_view.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: _buildSamplePlatformView(),
      ),
    );
  }

  Widget _buildSamplePlatformView() {
    return ExtendedPlatformView(
      config: const ExtendedPlatformViewConfig(
        viewType: 'sample_platform_view',
        androidCompositionMode: AndroidCompositionMode.hybridComposition,
        creationParams: "initial text",
      ),
      methodChannelDelegate: MethodChannelDelegate(
        onCreate: (channel) async {
          await Future.delayed(const Duration(seconds: 3));
          channel.invokeMethod(
            'set_text',
            '3 seconds elapsed',
          );
        },
      ),
    );
  }
}

更多关于Flutter扩展平台视图插件extended_platform_view的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter扩展平台视图插件extended_platform_view的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


extended_platform_view 是一个用于在 Flutter 应用中嵌入原生视图的插件。它是对 Flutter 官方 PlatformView 的扩展,提供了更强大的功能和更灵活的配置选项。通过 extended_platform_view,你可以在 Flutter 应用中嵌入 Android 的 View 或 iOS 的 UIView,并且可以更自由地控制这些原生视图的布局和交互。

安装

首先,在 pubspec.yaml 文件中添加 extended_platform_view 依赖:

dependencies:
  flutter:
    sdk: flutter
  extended_platform_view: ^1.0.0

然后运行 flutter pub get 来安装依赖。

使用方法

1. 创建原生视图

在 Android 和 iOS 平台上分别创建原生视图。

Android

在 Android 项目中,创建一个自定义的 View。例如,创建一个 MyNativeView

public class MyNativeView extends FrameLayout {
    public MyNativeView(Context context) {
        super(context);
        // 初始化你的视图
        TextView textView = new TextView(context);
        textView.setText("Hello from Android");
        addView(textView);
    }
}
iOS

在 iOS 项目中,创建一个自定义的 UIView。例如,创建一个 MyNativeView

#import <UIKit/UIKit.h>

[@interface](/user/interface) MyNativeView : UIView
[@end](/user/end)

[@implementation](/user/implementation) MyNativeView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        UILabel *label = [[UILabel alloc] initWithFrame:self.bounds];
        label.text = @"Hello from iOS";
        label.textAlignment = NSTextAlignmentCenter;
        [self addSubview:label];
    }
    return self;
}

[@end](/user/end)

2. 在 Flutter 中使用 extended_platform_view

在 Flutter 中,使用 ExtendedPlatformView 部件来嵌入原生视图。

import 'package:flutter/material.dart';
import 'package:extended_platform_view/extended_platform_view.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ExtendedPlatformView Example')),
        body: Center(
          child: ExtendedPlatformView(
            viewType: 'my_native_view', // 视图类型标识符
            creationParams: {}, // 传递给原生视图的参数
            creationParamsCodec: StandardMessageCodec(), // 参数编码器
            onPlatformViewCreated: (int id) {
              // 原生视图创建完成后的回调
              print("Native view created with id: $id");
            },
          ),
        ),
      ),
    );
  }
}

3. 注册原生视图工厂

在 Android 和 iOS 平台代码中,注册 ExtendedPlatformView

Android

MainActivity.kt 中注册视图工厂:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformViewFactory
import io.flutter.plugin.platform.PlatformView

class MyNativeViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        return MyNativeView(context)
    }
}

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        flutterEngine.platformViewsController.registry
            .registerViewFactory("my_native_view", MyNativeViewFactory())
    }
}
iOS

AppDelegate.m 中注册视图工厂:

#import "AppDelegate.h"
#import "MyNativeView.h"
#import "FlutterExtendedPlatformViewFactory.h"

[@interface](/user/interface) MyNativeViewFactory : NSObject <FlutterPlatformViewFactory>
[@end](/user/end)

[@implementation](/user/implementation) MyNativeViewFactory

- (NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame
                                   viewIdentifier:(int64_t)viewId
                                        arguments:(id _Nullable)args {
    return [[MyNativeView alloc] initWithFrame:frame];
}

[@end](/user/end)

[@implementation](/user/implementation) AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;
    FlutterEngine *engine = controller.engine;
    
    NSObject<FlutterBinaryMessenger> *messenger = [engine binaryMessenger];
    FlutterExtendedPlatformViewFactory *factory = [[FlutterExtendedPlatformViewFactory alloc] initWithMessenger:messenger];
    [factory registerViewFactory:[[MyNativeViewFactory alloc] init] withId:@"my_native_view"];
    
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

[@end](/user/end)
回到顶部