Flutter Platform View:在 Flutter 中使用Android、iOS的原生 View

860 阅读2分钟
原文链接: mp.weixin.qq.com

code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群

作者:ImWiki链接:https://www.jianshu.com/p/8d74a7318c26声明:本文已获ImWiki授权发表,转发等请联系原作者授权

我们在进行Flutter开发的时候,有时候是需要用到原生的View,比如WebView、MapView、第三方广告SDK等,Flutter提供了AndroidView、UiKitView可以实现相关功能。

创建项目

这里以在Flutter显示原生的TextView为案例,展示如何实现,创建项目过程这里不展示,建议使用Android Studio进行开发。

编写平台相关的代码

Android

创建PlatformView类

class AndroidTextView(context: Context) : PlatformView {    val contentView: TextView = TextView(context)    override fun getView(): View {        return contentView    }    override fun dispose() {}}

创建PlatformViewFactory类

class AndroidTextViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {        val androidTextView = AndroidTextView(context)        androidTextView.contentView.id = viewId        val params = args?.let { args as Map<*, *> }        val text = params?.get("text") as CharSequence?        text?.let {            androidTextView.contentView.text = it        }        return androidTextView    }}

注册工厂,不同版本的注册方式有所不同,这里是1.12.13版本

class MainActivity : FlutterActivity() {    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {        GeneratedPluginRegistrant.registerWith(flutterEngine)        val registry = flutterEngine.platformViewsController.registry        registry.registerViewFactory("platform_text_view", AndroidTextViewFactory())    }}

iOS

第一步:在info.plist增加io.flutter.embedded_views_preview=true,至关重要。

第二步:创建 PlatformTextView.swift

import Foundationimport Flutterclass PlatformTextView: NSObject,FlutterPlatformView {    let frame: CGRect;    let viewId: Int64;    var text:String = ""    init(_ frame: CGRect,viewID: Int64,args :Any?) {        self.frame = frame        self.viewId = viewID        if(args is NSDictionary){            let dict = args as! NSDictionary            self.text = dict.value(forKey: "text") as! String        }    }    func view() -> UIView {        let label = UILabel()        label.text = self.text        label.textColor = UIColor.red        label.frame = self.frame        return label    }}

第三步:创建PlatformTextViewFactory.swift

import Foundationimport Flutterclass PlatformTextViewFactory: NSObject,FlutterPlatformViewFactory {    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {        return PlatformTextView(frame,viewID: viewId,args: args)    }    func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {        return FlutterStandardMessageCodec.sharedInstance()    }}

第四步:在 AppDelegate.swift 注册

@UIApplicationMain@objc class AppDelegate: FlutterAppDelegate {  override func application(    _ application: UIApplication,    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?  ) -> Bool {    GeneratedPluginRegistrant.register(with: self)    let factory = PlatformTextViewFactory()    let registrar = self.registrar(forPlugin: "platform_text_view_plugin")    registrar.register(factory, withId: "platform_text_view")    return super.application(application, didFinishLaunchingWithOptions: launchOptions)  }}

编写Flutter代码

import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';import 'package:flutter/services.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Flutter Demo',      theme: ThemeData(        primarySwatch: Colors.blue,      ),      home: MyHomePage(title: 'Flutter Demo Home Page'),    );  }}class MyHomePage extends StatefulWidget {  MyHomePage({Key key, this.title}) : super(key: key);  final String title;  @override  _MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> {  Widget getPlatformTextView() {    if (defaultTargetPlatform == TargetPlatform.android) {      return AndroidView(          viewType: "platform_text_view",          creationParams: <String, dynamic>{"text": "Android Text View"},          creationParamsCodec: const StandardMessageCodec());    } else if (defaultTargetPlatform == TargetPlatform.iOS) {      return UiKitView(          viewType: "platform_text_view",          creationParams: <String, dynamic>{"text": "iOS Label"},          creationParamsCodec: const StandardMessageCodec());    } else {      return Text("Not supported");    }  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text(widget.title),      ),      body:getPlatformTextView(),    );  }}

运行

完整代码

https://github.com/taoweiji/FlutterPlatformViewExample

参考

https://60devs.com/how-to-add-native-code-to-flutter-app-using-platform-views-android.html

相关阅读

1 Flutter1.12 升级后的问题2 Flutter 实现 App 内更新安装包3 面对Flutter,我终于迈出了第一步4 使用Flutter一年后,这是我得到的经验5 Flutter 与原生交互总结

如果你有写博客的好习惯 欢迎投稿

点个在看,小生感恩 ❤️