Flutter 插件开发

},

/// 用来编码 creationParams 的形式,可选 [StandardMessageCodec], [JSONMessageCodec], [StringCodec], or [BinaryCodec]

/// 如果存在 creationParams,则该值不能为null

creationParamsCodec: const StandardMessageCodec(),

);

}else if(Platform.isIOS){///加载iOS原生视图

return UiKitView(

viewType: ‘testView’,///视图标识符 要和原生 保持一致 要不然加载不到视图

onPlatformViewCreated:onPlatformViewCreated,///原生视图创建成功的回调

creationParams: <String, dynamic>{ ///给原生传递初始化参数 就是上面定义的初始化参数

‘titleStr’:widget.titleStr,

},

/// 用来编码 creationParams 的形式,可选 [StandardMessageCodec], [JSONMessageCodec], [StringCodec], or [BinaryCodec]

/// 如果存在 creationParams,则该值不能为null

creationParamsCodec: const StandardMessageCodec(),

);

}else{

return Text(‘这个平台老子不支持’);

}

}

///我也是刚学Flutter 所以我理解的:这个基本上是固定写法 哈哈

Future onPlatformViewCreated(id) async {

if (widget.onCreated == null) {

return;

}

widget.onCreated(new TestFlutterPluginDemo.init(id));

}

}

复制代码

截止到现在Dart的主要代码就写完了,代码中的注释已经很细了,小伙伴们可以跟着代码一步一步的敲一下,增强一下记忆力和代码熟悉程度. 剩下的就是在main.dart 里面加载视图了,

import ‘package:flutter/material.dart’;

import ‘package:test_flutter_plugin_demo/test_flutter_plugin_demo.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,///使用原生视图

)

],

)

),

);

}

void onTestViewCreated(testFlutterPluginDemo){

this.testFlutterPluginDemo = testFlutterPluginDemo;

}

}

复制代码

在main.dart里面添加加载视图的代码后 插件开发 Dart相关代码就写完了,下面咱们开始写原生代码了,强调一下哈 iOS 代码为例 OC语言

开始原生代码

让我们先看一下测试工程的代码文件目录

9.jpg

发现有两个文件 GeneratedPluginRegistrant.h 和 GeneratedPluginRegistrant.m,但是这两个文件不是咱们需要敲代码的页面,咱们敲代码的页面隐藏的比较深 在下面的这个目录里

10.jpg

一定要在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 里面添加

复制代码

现在让我们运行一下 看看效果吧

11.jpg

加载原生视图到现在就 完成了 下面让我们开始来学习 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(

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后说一下我的学习路线

其实很简单就下面这张图,含概了Android所有需要学的知识点,一共8大板块:

  1. 架构师筑基必备技能
  2. Android框架体系架构(高级UI+FrameWork源码)
  3. 360°Androidapp全方位性能调优
  4. 设计思想解读开源框架
  5. NDK模块开发
  6. 移动架构师专题项目实战环节
  7. 移动架构师不可不学习微信小程序
  8. 混合开发的flutter

Android学习的资料

我呢,把上面八大板块的分支都系统的做了一份学习系统的资料和视频,大概就下面这些,我就不全部写出来了,不然太长了影响大家的阅读。

330页PDF Android学习核心笔记(内含上面8大板块)

Android学习的系统对应视频

总结

我希望通过我自己的学习方法来帮助大家去提升技术:

  • 1、多看书、看源码和做项目,平时多种总结

  • 2、不能停留在一些基本api的使用上,应该往更深层次的方向去研究,比如activity、view的内部运行机制,比如Android内存优化,比如aidl,比如JNI等,并不仅仅停留在会用,而要通过阅读源码,理解其实现原理

  • 3、同时对架构是有一定要求的,架构是抽象的,但是设计模式是具体的,所以一定要加强下设计模式的学习

  • 4、android的方向也很多,高级UI,移动架构师,数据结构与算法和音视频FFMpeg解码,如果你对其中一项比较感兴趣,就大胆的进阶吧!

希望大家多多点赞,转发,评论加关注,你们的支持就是我继续下去的动力!加油!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

微信小程序**
8. 混合开发的flutter

[外链图片转存中…(img-JAz2RRsk-1712262502050)]

Android学习的资料

我呢,把上面八大板块的分支都系统的做了一份学习系统的资料和视频,大概就下面这些,我就不全部写出来了,不然太长了影响大家的阅读。

330页PDF Android学习核心笔记(内含上面8大板块)

[外链图片转存中…(img-AreISAXv-1712262502050)]

Android学习的系统对应视频

总结

我希望通过我自己的学习方法来帮助大家去提升技术:

  • 1、多看书、看源码和做项目,平时多种总结

  • 2、不能停留在一些基本api的使用上,应该往更深层次的方向去研究,比如activity、view的内部运行机制,比如Android内存优化,比如aidl,比如JNI等,并不仅仅停留在会用,而要通过阅读源码,理解其实现原理

  • 3、同时对架构是有一定要求的,架构是抽象的,但是设计模式是具体的,所以一定要加强下设计模式的学习

  • 4、android的方向也很多,高级UI,移动架构师,数据结构与算法和音视频FFMpeg解码,如果你对其中一项比较感兴趣,就大胆的进阶吧!

希望大家多多点赞,转发,评论加关注,你们的支持就是我继续下去的动力!加油!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Podspec是CocoaPods使用的一种文件格式,用于描述一个库的元数据信息。在Flutter插件开发中,我们需要使用Podspec文件来描述iOS平台上的插件信息,以便其他开发者在使用我们的插件时能够正确地集成到他们的项目中。 下面是一些关于Podspec语法的整理: 1. Podspec文件的命名应该以插件的名称为准,并以`.podspec`作为文件扩展名,如`flutter_my_plugin.podspec`。 2. Podspec文件应该包含以下信息: - 插件的名称和版本号 - 插件的描述 - 作者信息 - 插件的许可证 - 插件依赖的库和框架 - 插件的源代码文件和资源文件 3. Podspec文件的基本结构如下: ``` Pod::Spec.new do |s| s.name = '插件名称' s.version = '插件版本号' s.summary = '插件描述' s.homepage = '插件主页' s.license = '插件许可证' s.author = { '作者名称' => '作者邮箱' } s.source = { :git => '插件源代码仓库地址', :tag => '插件版本号' } s.dependency '依赖库名称', '依赖库版本号' # 插件依赖的库和框架 s.source_files = '插件源代码文件路径' # 插件的源代码文件 s.resource_bundles = { '插件资源文件名称' => ['插件资源文件路径'] } # 插件的资源文件 end ``` 4. 在描述依赖库时,可以使用以下语法: - `s.dependency '库名称'`:插件依赖的库名称。 - `s.dependency '库名称', '~> 版本号'`:插件依赖的库名称和版本号,其中`~>`表示兼容某个版本号及以上的库。 - `s.dependency '库名称', '>= 版本号'`:插件依赖的库名称和版本号,其中`>=`表示需要某个版本号及以上的库。 5. 在描述源代码文件和资源文件时,可以使用以下语法: - `s.source_files = '路径/**/*.{h,m,swift}'`:插件的源代码文件路径,可以使用通配符`*`和`**`。 - `s.resource_bundles = { 'Bundle名称' => ['路径/**/*'] }`:插件的资源文件,可以使用通配符`*`和`**`。 以上就是关于Podspec语法的整理,希望能对Flutter插件开发有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值