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

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 Foundation
import Flutter
class 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 Foundation
import Flutter

class 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 与原生交互总结

如果你有写博客的好习惯

欢迎投稿

点个在看,小生感恩❤️

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值