27 | 如何在Dart层兼容Android/iOS平台特定实现?(二)
陈航
该思维导图由 AI 生成,仅供参考
你好,我是陈航。
在上一篇文章中,我与你介绍了方法通道,这种在 Flutter 中实现调用原生 Android、iOS 代码的轻量级解决方案。使用方法通道,我们可以把原生代码所拥有的能力,以接口形式提供给 Dart。
这样,当发起方法调用时,Flutter 应用会以类似网络异步调用的方式,将请求数据通过一个唯一标识符指定的方法通道传输至原生代码宿主;而原生代码处理完毕后,会将响应结果通过方法通道回传至 Flutter,从而实现 Dart 代码与原生 Android、iOS 代码的交互。这,与调用一个本地的 Dart 异步 API 并无太多区别。
通过方法通道,我们可以把原生操作系统提供的底层能力,以及现有原生开发中一些相对成熟的解决方案,以接口封装的形式在 Dart 层快速搞定,从而解决原生代码在 Flutter 上的复用问题。然后,我们可以利用 Flutter 本身提供的丰富控件,做好 UI 渲染。
底层能力 + 应用层渲染,看似我们已经搞定了搭建一个复杂 App 的所有内容。但,真的是这样吗?
构建一个复杂 App 都需要什么?
别急,在下结论之前,我们先按照四象限分析法,把能力和渲染分解成四个维度,分析构建一个复杂 App 都需要什么。
图 1 四象限分析法
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
Flutter中使用方法通道和平台视图实现了Dart层与原生Android、iOS代码的交互和兼容。方法通道将原生代码的能力以接口形式提供给Dart,实现异步调用和数据传输。平台视图解决了原生视图复用问题,允许在Flutter中嵌入原生系统的视图,并实现与Flutter一致的交互体验。文章指出Flutter和方法通道只能解决应用层渲染、应用层能力和底层能力,而对于涉及底层渲染的场景,如浏览器、相机、地图等,重新在Flutter上开发一套显然不太现实。在这种情况下,使用平台视图成为一个不错的选择。通过示例代码,展示了在Flutter中使用AndroidView和UiKitView来实现原生视图的接口调用,以及在原生代码中完成视图创建的封装和绑定关系的实现。总的来说,本文通过方法通道和平台视图的介绍,为读者提供了在Flutter中实现Dart层与原生Android、iOS代码兼容的技术方案,为构建复杂App提供了有益的指导和思路。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Flutter 核心技术与实战》,新⼈⾸单¥59
《Flutter 核心技术与实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(22)
- 最新
- 精选
- 宇思考题实现思路 dart层设置颜色参数的方法: changeBackgroundColor(int r, int g, int b) async { _channel.invokeMethod('changeBackgroundColor', {"r":r, "g":g, "b":b}); } dart层调用: controller.changeBackgroundColor(0, 255, 255) android native层实现: if (methodCall.method.equals("changeBackgroundColor")) { int r = methodCall.argument("r"); int g = methodCall.argument("g"); int b = methodCall.argument("b"); view.setBackgroundColor(Color.rgb(r, g, b)); result.success(0); }else { result.notImplemented(); }
作者回复: 赞👍
2019-09-026 - 舒大飞反过来,可以在原生页面中嵌入一小块Flutter视图吗
作者回复: 可以,Activity内嵌flutterView其实就是这种方式,只是这个视图大小是整个屏幕
2019-10-1022 - kenneniOS中的frame参数并没有用到,flutter是怎么把宽高传给iOS来展示的呢?
作者回复: 你回忆一下iOS中autolayout和autorelease中父容器的布局变化对于组件布局的影响
2019-11-26 - Miracle_请问下,嵌入了原生视图后,如果嵌入的是较为复杂的视图,视图带走点击等交互事件,应该在哪边设置监听或者处理呢?
作者回复: 看具体场景。我的建议是,如果点击交互的事件处理是能够在原生视图内搞定的,原生视图自己监听就好。否则就需要传出来让flutter处理
2019-10-23 - 和小胖思考题如下: //声明修改原生控件背景的方法 changeBgColor() async { try { _methodChannel.invokeMethod("changeBgColor", { "color1": Random().nextInt(255), "color2": Random().nextInt(255), "color3": Random().nextInt(255) }); } catch (e) { print(e); } } override fun onMethodCall(p0: MethodCall, p1: MethodChannel.Result) { when (p0.method) { "changeBgColor" -> { view.setBackgroundColor(Color.rgb(p0.argument<Int>("color1")!!, p0.argument<Int>("color2")!!, p0.argument<Int>("color3")!!)) p1.success(0) } //如果是别的方法则返回未实现 else -> p1.notImplemented() } }
作者回复: 厉害👍
2019-10-14 - 许童童妙啊,通过平台视图,Flutter就可以使用原生视图了,这样,基本所有需求都可以实现了。如果社区再繁荣一点,许多组件都可以拿来即用,那开发需求的速度就是相当快了。2019-08-2915
- Verios每次 widget 重建,都会create一个原生 view 吗?2020-03-1912
- jianweifloatingActionButton: FloatingActionButton( onPressed: () => controller.changeBackground('#FFFFFF'), ), Future<void> changeBackground(String colorString) async { try { return _channel.invokeMethod('changeBackgroundColor', <String, dynamic> { 'color': colorString }); } catch (e) { } } - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([call.method isEqualToString:@"changeBackgroundColor"]) { NSString *colorString = call.arguments[@"color"]; if (colorString.length != 0) { _templcateView.backgroundColor = [UIColor colorWithHexString:colorString]; result(@0); return; } } result(FlutterMethodNotImplemented); }2020-01-082
- 无名iOS 平台视图中:-(NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{} 为何frame的值都是(0.0, 0.0, 0.0, 0.0),为何没有宽高?这里不应该是显示的视图大小吗?2020-08-141
- 星星这个在io.flutter.embedding.android.FlutterActivity中如何绑定呢,没有响应的方法啊2020-03-1611
收起评论