《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
完整开源地址:https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
///定义一个测试类的属性 用来调用原生方法 和原生交互
var testFlutterPluginDemo;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
///初始化 测试视图的类
TestView testView = new TestView(
onCreated: onTestViewCreated,
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(‘Plugin example app’),
),
body: Column(
children: [
Container(
height: 200,
width: 400,
child: testView,///使用原生视图
)
],
)
),
);
}
void onTestViewCreated(testFlutterPluginDemo){
this.testFlutterPluginDemo = testFlutterPluginDemo;
}
}
复制代码
在main.dart里面添加加载视图的代码后 插件开发 Dart相关代码就写完了,下面咱们开始写原生代码了,强调一下哈 iOS 代码为例 OC语言
开始原生代码
让我们先看一下测试工程的代码文件目录
发现有两个文件 GeneratedPluginRegistrant.h 和 GeneratedPluginRegistrant.m,但是这两个文件不是咱们需要敲代码的页面,咱们敲代码的页面隐藏的比较深 在下面的这个目录里
一定要在pod /Development Pods 里面找到Classes文件夹里的这两个文件 开发, 新建类也要在这个目录里面, 使用过iOS 组件发开发的同学一定很熟悉,原理差不多哟 好了开始原生代码开发吧 先让我们新建一个Factory 来连接 Flutter 的视图吧 新建的 Factory 要继承与 NSObject 然后在新建一个view类也要继承与NSObject 来写原生页面布局 两个类的代码如下
factory.h
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface TestFlutterPluginViewFactory : NSObject
/// 重写一个构造方法 来接收 Flutter 相关蚕食
/// @param messenger Flutter类 包含回调方法等信息
- (instancetype)initWithMessenger:(NSObject*)messenger;
@end
复制代码
factory.m
#import “TestFlutterPluginViewFactory.h”
#import “TestFlutterPluginView.h”
@interface TestFlutterPluginViewFactory ()
@property(nonatomic)NSObject* messenger;
@end
@implementation TestFlutterPluginViewFactory
- (instancetype)initWithMessenger:(NSObject*)messenger {
self = [super init];
if (self) {
self.messenger = messenger;
}
return self;
}
#pragma mark – 实现FlutterPlatformViewFactory 的代理方法
- (NSObject*)createArgsCodec {
return [FlutterStandardMessageCodec sharedInstance];
}
/// FlutterPlatformViewFactory 代理方法 返回过去一个类来布局 原生视图
/// @param frame frame
/// @param viewId view的id
/// @param args 初始化的参数
- (NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{
TestFlutterPluginView *testFlutterPluginView = [[TestFlutterPluginView alloc] initWithFrame:frame viewId:viewId args:args messager:self.messenger];
return testFlutterPluginView;
}
@end
复制代码
testView.h
#import <Foundation/Foundation.h>
#include <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface TestFlutterPluginView : NSObject
- (id)initWithFrame:(CGRect)frame
viewId:(int64_t)viewId
args:(id)args
messager:(NSObject*)messenger;
@end
复制代码
testView.m
#import “TestFlutterPluginView.h”
@interface TestFlutterPluginView ()
/** channel*/
@property (nonatomic, strong) FlutterMethodChannel *channel;
@end
@implementation TestFlutterPluginView
{
CGRect _frame;
int64_t _viewId;
id _args;
}
- (id)initWithFrame:(CGRect)frame
viewId:(int64_t)viewId
args:(id)args
messager:(NSObject*)messenger
{
if (self = [super init])
{
_frame = frame;
_viewId = viewId;
_args = args;
///建立通信通道 用来 监听Flutter 的调用和 调用Fluttter 方法 这里的名称要和Flutter 端保持一致
_channel = [FlutterMethodChannel methodChannelWithName:@“test_flutter_plugin_demo” binaryMessenger:messenger];
__weak typeof(self) weakSelf = self;
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
[weakSelf onMethodCall:call result:result];
}];
}
return self;
}
- (UIView *)view{
UIView *nativeView = [[UIView alloc] initWithFrame:_frame];
nativeView.backgroundColor = [UIColor redColor];
return nativeView;
}
#pragma mark – Flutter 交互监听
-(void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result{
}
复制代码
工厂类和视图类都创建完了,现在可以到 刚开始的模板里创建的 TestFlutterPluginDemoPlugin 这个类里去做关联了 是/Development Pods 里面找到Classes文件夹里的这两个文件 删掉自带的无用的代码 连接的实例代码如下 TestFlutterPluginDemoPlugin.h
#import “TestFlutterPluginDemoPlugin.h”
#import “TestFlutterPluginViewFactory.h”
@implementation TestFlutterPluginDemoPlugin
- (void)registerWithRegistrar:(NSObject*)registrar {
TestFlutterPluginViewFactory *testViewFactory = [[TestFlutterPluginViewFactory alloc] initWithMessenger:registrar.messenger];
//这里填写的id 一定要和dart里面的viewType 这个参数传的id一致
[registrar registerViewFactory:testViewFactory withId:@“testView”];
}
@end
复制代码
现在显示视图的代码就写完了 想要加载成功还要在 info.plist 里面添加
复制代码
现在让我们运行一下 看看效果吧
加载原生视图到现在就 完成了 下面让我们开始来学习 Flutter 方法互相调用和传值吧
Flutter 和 原生 交互
还是让我们先写Dart 代码 在上面咱们创建的 TestFlutterPluginDemo 这个类里面添加 和原生交互代码
typedef void TestViewCreatedCallback(TestFlutterPluginDemo controller);
class TestFlutterPluginDemo {
MethodChannel _channel;
TestFlutterPluginDemo.init(int id){
_channel = new MethodChannel(‘test_flutter_plugin_demo’);
_channel.setMethodCallHandler(platformCallHandler);///设置原生参数监听
}
///Flutter 调用原生
///这里我传了一个 字符串 当然也可以传Map
Future changeNativeTitle(String str) async{
return _channel.invokeListMethod(‘changeNativeTitle’,str);
}
///实现监听原生方法回调
Future platformCallHandler(MethodCall call) async {
switch (call.method) {
case “clickAciton”:
print(‘收到原生回调 ---- $call.arguments’);
return ;
break;
}
}
}
复制代码
然后让我们在main.dart 里面添加一个按钮用来触发 调用原生
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
///定义一个测试类的属性 用来调用原生方法 和原生交互
var testFlutterPluginDemo;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
///初始化 测试视图的类
TestView testView = new TestView(
onCreated: onTestViewCreated,
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(‘Plugin example app’),
),
body: Column(
children: [
Container(
height: 200,
width: 400,
child: testView,///使用原生视图
),
FloatingActionButton( ///添加一个按钮 用来触发原生调用
onPressed: onNativeMethon, ///点击方法里面调用原生