PlatformView 就是AndroidViewUIKitView的总称,允许原生端view嵌入到flutter项目 中的 Widget

PlatformView演示效果

接下来简单的演示下它的基本使用规则。

1、新建一个Flutter项目,然后在main.dart中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/services.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Platform.isIOS
? const UiKitView(
viewType: "platform_text_view",
creationParams: <String, dynamic>{"text": "iOS Label"},
creationParamsCodec: StandardMessageCodec(),
)
: const AndroidView(
viewType: "platform_text_view",
creationParams: <String, dynamic>{"text": "Android Text View"},
creationParamsCodec: StandardMessageCodec(),
),
);
}
}

其中,iOS对应的是UiKitView ,传递的参数是iOS Label,唯一标识符是:platform_text_view 。android对应的是AndroidView ,传递的参数是Android Text View,唯一标识符是platform_text_view

iOS一侧:

新建PlatformTextView.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
}
}

新建PlatformTextView.swift

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import UIKit
import Flutter

@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)
}
}

然后在info.plist中添加:

1
<key>io.flutter.embedded_views_preview</key>

Android一侧:

新建AndroidTextView.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.platformview
import android.content.Context
import android.graphics.Color
import android.view.View
import android.widget.TextView
import io.flutter.plugin.platform.PlatformView

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

新建AndroidTextViewFactory.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.platformview

import android.content.Context
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.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
}
}

修改MainActivity.kt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.platformview

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

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

OK,回到flutter工程中,重新运行即可。

本文源码

其他:

Android原生工程中添加Flutter模块

iOS原生工程中添加Flutter模块