Flutter插件开发(原生View显示)
该篇文章记录分析,Flutter插件开发中,怎样通过dart调用原生UI,以iOS为例
核心是Flutter.framework中的FlutterPlatformViews.h文件.
其中包括两个协议,源码如下
@protocol FlutterPlatformView
/**
* Returns a reference to the `UIView` that is wrapped by this `FlutterPlatformView`.
*/
- (UIView*)view;
@end
FLUTTER_EXPORT
@protocol FlutterPlatformViewFactory
/**
* Create a `FlutterPlatformView`.
*
* Implemented by iOS code that expose a `UIView` for embedding in a Flutter app.
*
* The implementation of this method should create a new `UIView` and return it.
*
* @param frame The rectangle for the newly created `UIView` measued in points.
* @param viewId A unique identifier for this `UIView`.
* @param args Parameters for creating the `UIView` sent from the Dart side of the Flutter app.
* If `createArgsCodec` is not implemented, or if no creation arguments were sent from the Dart
* code, this will be null. Otherwise this will be the value sent from the Dart code as decoded by
* `createArgsCodec`.
*/
- (NSObject*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args;
/**
* Returns the `FlutterMessageCodec` for decoding the args parameter of `createWithFrame`.
*
* Only needs to be implemented if `createWithFrame` needs an arguments parameter.
*/
@optional
- (NSObject*)createArgsCodec;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERPLATFORMVIEWS_H_
可以看到FlutterPlatformView协议要求实现一个名为view的UIView对象.所以天然UIViewController即可.
FlutterPlatformViewFactory协议要求实现一个初始化方法, 返回一个实现了FlutterPlatformView协议的对象.按上面的说法,很明显返回一个UIViewController- (NSObject*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args;
所以综上,flutter中显示原生View,其实就是通过一个实现了FlutterPlatformViewFactory协议的object对象,来返回一个UIViewController对象,该UIViewController对象中的View就是我们要展示在Flutter层的自定义原生View了.
同样通过实现了FlutterPluginRegistrar协议的对象来实现factoryID注册.
该对象便是插件初始化方法
+ (void)registerWithRegistrar:(NSObject*)registrar中的registrar对象.
所有方法的注册,View的生成都是通过全局的registrar对象来注册.
注册factoryId的核心方法是- (void)registerViewFactory:(NSObject*)factory
withId:(NSString*)factoryId;
这样通过registrar注册factoryId来实现flutter层和原生层View的绑定.
Flutter层的调用
大概就是这样,其中FactoryID就是在注册factory时的自定义ID了Widget _view = Platform.isIOS
? UiKitView(
viewType: "FactoryID",
creationParams: {"name": _name},
creationParamsCodec: StandardMessageCodec(),
)
: AndroidView(
viewType: "FactoryID",
creationParams: {"name": _name},
creationParamsCodec: StandardMessageCodec(),
);
通过这种方式来将原生中View包成一个flutter层面的widget来使用.如果没有参数, creationParamsCodec可以为null.
可见iOS的View为UiKitView方法,安卓的使用AndroidView,本文以iOS为主,安卓原理相同,都是通过一个全局的registrar来实现flutter层和原生层的调度.
其中相关文件主要也是PluginRegistry,PlatformView,PlatformViewFactoryimport io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
注册方法大概如下registrar.platformViewRegistry().registerViewFactory("FactoryID",
new ddViewFactory(new StandardMessageCodec(),_registrar));
其中ddViewFactory大概如下public class ddViewFactory extends PlatformViewFactory {
...
}版权属于:邢迪的平行时空
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可