填写插件名称
红线圈起来的地方根据自己的语言选择 默认安卓项目是java iOS项目是Object-c,要是需要Kotlin 和 Swift的话 要打上勾,我是一直使用Object-c 所以下面的讲解演示用OC 来写
这是新创建完的插件模板目录
写原生代码的话 就在example 目录里找到对应的iOS 或者 是安卓目录,以iOS为例 新创建的iOS代码是不包含 pod文件夹的所以无法运行 需要先在example里面的iOS 文件夹里运行 pod install 来安装需要的依赖包
然后就可以运行示例工程了
至此Flutter 插件开发准备工作就结束了,下面让我们进入真正的插件开发吧
磨拳霍霍向猪羊---- 插件开发
让我们先从Dart代码开始
这是模板刚创建的dart代码
我们先简化一下代码把没用的代码删掉 再把相关报错的代码注释掉
///先定义一个controller创建成功回调 后面会用到
typedef void TestViewCreatedCallback(TestFlutterPluginDemo controller);
class TestFlutterPluginDemo {
MethodChannel _channel;
TestFlutterPluginDemo.init(int id){
_channel = new MethodChannel(‘test_flutter_plugin_demo’);
}
}
复制代码
TestFlutterPluginDemo 这个类 我理解的是 主要负责和原生进行交互,调用原生的方法和监听原生方法, 然后让我们新建一个view类主要是加载原生的视图
///我是使用的 StatefulWidget 使用StatelessWidget 也是一样
class TestView extends StatefulWidget {
///根据自己的需求创建初始化参数
final TestViewCreatedCallback onCreated; ///是上面创建的回调
final String titleStr;
TestView({
Key key,
this.onCreated,
this.titleStr,
});
@override
_TestViewState createState() => _TestViewState();
}
class _TestViewState extends State {
@override
Widget build(BuildContext context) {
return Container(
child: _loadNativeView(),
);
}
///加载原生视图
Widget _loadNativeView(){
///根据不同的平台显示相应的视图
if(Platform.isAndroid){ ///加载安卓原生视图
return AndroidView(
viewType: ‘testView’,///视图标识符 要和原生 保持一致 要不然加载不到视图
onPlatformViewCreated:onPlatformViewCreated,///原生视图创建成功的回调
creationParams: <String, dynamic>{ ///给原生传递初始化参数 就是上面定义的初始化参数
‘titleStr’:widget.titleStr,
},
/// 用来编码 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语言
开始原生代码
让我们先看一下测试工程的代码文件目录
发现有两个文件 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];
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/c6ce2e1f429072394442ba656890c3be.jpeg)
结尾
我还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
-kRYy8vA3-1711817712221)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/c6ce2e1f429072394442ba656890c3be.jpeg)
结尾
我还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
[外链图片转存中…(img-8AO6gtcw-1711817712222)]