Flutter Platform View 使用及原理简析

本文介绍了Flutter Platform View的概念和简单使用,详细讲解了在Android和iOS两侧如何创建和注册平台视图,并给出了在Flutter项目中使用的示例。通过源码分析解答了Platform View的大小控制、渲染位置和性能开销等问题,最后探讨了如何开发一个Platform View并提供相关资源链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是 platform view?

由于 Flutter 诞生于 Android 、iOS 非常成熟的时代背景,为了能让一些现有的 native 控件直接引用到 Flutter app 中,Flutter 团队提供了 AndroidView 、UIKitView 两个 widget 来满足需求,比如说 Flutter 中的 Webview、MapView,暂时无需使用 Flutter 重新开发一套。

其实 platform view 就是 AndroidView 和 UIKitView 的总称,允许将 native view 嵌入到了 flutter widget 体系中,完成 Datr 代码对 native view 的控制。

简单使用

此处仅是简单使用,有很多不合理的代码,目的仅是让初学者能完成展示,后面会有具体的 framework 代码分析,及官方维护的 platform view 的分析。

先看一下效果吧

存在与 native 交互的代码,建议用一个 plugin 来实现内部逻辑。

Plugin: exposing an Android or iOS API for developers

Flutter 侧

创建 Flutter plugin (建议使用 Android Studio),如果使用命令行,可以执行如下命令:

flutter create --org net.loosash --template = plugin share_platform_plugin

接下来在我们的插件工程里创建一个 widget 用来包裹 platform view。便于使用

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

/// 这里使用了 statelessWidget
class PlatformTextWidget extends StatelessWidget {
   
   
  PlatformTextWidget({
   
   this.text});

  final String text;

  @override
  Widget build(BuildContext context) {
   
   
    // 根据运行平台判断执行代码
    if (defaultTargetPlatform == TargetPlatform.android) {
   
   
      return AndroidView(
        // 在 native 中的唯一标识符,需要与 native 侧的值相同
        viewType: "platform_text_view",
        // 在创建 AndroidView 的同时,可以传递参数
        creationParams: <String, dynamic>{
   
   "text": text},
        // 用来编码 creationParams 的形式,可选 [StandardMessageCodec], [JSONMessageCodec], [StringCodec], or [BinaryCodec]
        // 如果存在 creationParams,则该值不能为null
        creationParamsCodec: const StandardMessageCodec(),
      );
    } else if (defaultTargetPlatform == TargetPlatform.iOS) {
   
   
      return UiKitView(
        viewType: "platform_text_view",
        creationParams: <String, dynamic>{
   
   "text": text},
        creationParamsCodec: const StandardMessageCodec(),
      );
    } else {
   
   
      return Text("不支持的平台");
    }
  }
}

iOS 侧

在编辑Xcode中的iOS平台代码之前,首先确保代码至少已构建过一次。在创建的 plugin/example 目录下执行 build,如下:

cd share_platform_plugin/example
flutter build ios --no-codesign
或者执行 pod install

然后使用 Xcode 打开 share_platform_plugin/example/ios/Runner.xcworkspace,plugin 相关的代码目录很深,在 Pods/Development Pods/share_platform_plugin 内部,具体找到 SharePlatformPlugin.h 与 SharePlatformPlugin.m 目录即位我们操作的目录。

接下来我们先创建需要展示的 View ,这里仅以一个 UILabel 为例。

IOSTextView.h

#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interface IOSTextView : NSObject<FlutterPlatformView>

- (instancetype)initWithFrame:(CGRect)frame
                   viewIdentifier:(int64_t)viewId
                        arguments:(id _Nullable)args
                  binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end

NS_ASSUME_NONNULL_END

IOSTextView.m

#import <Foundation/Foundation.h>
#import "IOSTextView.h"

@implementation IOSTextView{
   
   
    int64_t _viewId;
    FlutterMethodChannel* _channel;
    UILabel * _uiLabel;
}


- (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject<FlutterBinaryMessenger> *)messenger{
   
   
    
    NSString *text = @"iOS端UILabel";

    if ([args isKindOfClass:[NSDictionary class]]) {
   
   
        NSDictionary *params = (NSDictionary *)args;
        if([[params allKeys] containsObject:@"text"]){
   
   
            if ([[params valueForKey:@"text"] isKindOfClass:[NSString class]]) {
   
   
                text= [params valueForKey:@"text"];
            }
        }
    }
    _uiLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    _uiLabel.textAlignment = NSTextAlignmentCenter;
    _uiLabel.text = text;
    _uiLabel.font = [UIFont systemFontOfSize:30];
    return self;
}

-(UIView *)view{
   
   
    return _uiLabel;
}

@end

然后创建 FlutterPlatformViewFactory

SharePlatformViewFactory.h

#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interface SharePlatformViewFactory : NSObject<FlutterPlatformViewFactory>

- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messager;

-(NSObject<FlutterMessageCodec> *)createArgsCodec;

-(NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args;

@end
NS_ASSUME_NONNULL_END

SharePlatformViewFactory.m

#import "SharePlatformViewFactory.h"
#import "IOSTextView.h"

@implementation SharePlatformViewFactory{
   
   
    NSObject<FlutterBinaryMessenger>*_messenger;
}

- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger> *)messager{
   
   
    self = [super init];
    if (self) {
   
   
        _messenger = messager;
    }
    return self;
}

-(NSObject<FlutterMessageCodec> *)createArgsCodec{
   
   
    return [FlutterStandardMessageCodec sharedInstance];
}

-(NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{
   
   
    IOSTextView *iosTextView = [[IOSTextView alloc] initWithFrame:frame viewIdentifier
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值