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

时间: 2020-02-23阅读: 15标签: Flutter

我们在进行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(),
    );
  }
}
作者:ImWiki
链接:https://www.jianshu.com/p/8d74a7318c26
站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/8359

在 Flutter 中玩转 Objective-C Block

dart_native 作为一条比 Channel 性能更高开发成本更低的超级通道,通过 C++ 调用 Native 的 API,深入底层且考虑全面。很多 Objective-C 接口的参数和返回值是 Block,所以这就需要支持用 Dart 语言创建和调用 Objective-C Block。

Flutter 国际化应用实战

借助App Store与Google Play,全世界任何一个国家的使用者都可以使用我们开发的应用,不过由于应用的使用者来自不同国家,所以在应用正式上架之前需要让应用能够支持多种语言,即应用的国际化。在Flutter开发中

Flutter事件监听

在大前端的开发中,必然存在各种各样和用户交互的情况:比如手指点击、手指滑动、双击、长按等等。在Flutter中,手势有两个不同的层次:

可能是Flutter上最简单的本地数据保存方案

local_cache_sync是一个非常简单易用的Flutter本地储存库,适用于在本地储存一列轻量数据(例如用户保存在本地的设备信息,或者缓存一系列用户信息),local_cache_sync的所有方法,包括保存与读取,都是同步的,而不是异步的。

Flutter 设置控件是否可见

共有两种实现比较简单的方式,第一种比较好理解,将一个控件的透明度设置成0,打到隐藏的目的。第二种办法是使用 SDK 自带的 Offstage 控件包裹。

面对Flutter,我终于迈出了第一步

早在一年前想学习下flutter,但当时对于它布局中地狱式的嵌套有点望而生畏,心想为什么嵌套这么复杂,就没有xml布局方式吗,用jsx方式也行啊,为什么要用dart而不用javascript,走开,劳资不学了。

打破重重阻碍,Flutter 和 Web 生态如何对接?

Flutter 设计之初是不考虑 Web 生态的,原因很简单:两种技术设计理念不同,强行融合很可能让彼此都丧失了优势。但是业界又有很多团队在做这种尝试,说明需求是存在的。今天,阿里无线开发专家门柳就来手把手教如何实现 Flutter 和 Web 生态的对接?

Flutter的布局和页面组件

在这里,你必须得安装好你的开发者环境,并且运行你的第一个flutter程序了。如果你还不知道怎么开始,请参考Flutter中文网安装教程或者Flutter官网安装教程进行安装环境。

Flutter的生命周期和路由

Flutter主要有两种:无状态的 StatelessWidget和有状态的 StatefulWidget,一个 StatelessWidget 是不能被改变的,比如:Icon、Text等。由于不可改变,因此并没有什么生命周期。

Flutter 之 ListView

在 Flutter 中,ListView 可以沿一个方向(垂直或水平方向)来排列其所有子 Widget,常被用于需要展示一组连续视图元素的场景;ListView 构造方法

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广