Flutter Platform View 使用及原理简析

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

什么是 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:fra
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值