Flutter 核心技术与实战
陈航
前美团点评高级技术专家
42432 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
Flutter 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

27 | 如何在Dart层兼容Android/iOS平台特定实现?(二)

增加颜色参数,实现动态变更原生视图颜色的需求
大部分原生代码能够实现的UI效果,完全可以用Flutter实现
避免在一个界面上同时实例化多个原生控件
转换不同的渲染数据会有较大的性能开销
实现精确控制原生视图展示的效果
在原生视图的封装类中注册方法通道
实现原生视图与Flutter视图的融合复用
提供平台视图工厂和视图标识符概念
通过代码封装,将原生视图组装成Flutter控件
解决原生渲染能力的复用问题
思考题
性能注意事项
动态调整原生视图样式
平台视图

该思维导图由 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
立即购买
登录 后留言

全部留言(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-02
    6
  • 舒大飞
    反过来,可以在原生页面中嵌入一小块Flutter视图吗

    作者回复: 可以,Activity内嵌flutterView其实就是这种方式,只是这个视图大小是整个屏幕

    2019-10-10
    2
    2
  • kennen
    iOS中的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-29
    1
    5
  • Verios
    每次 widget 重建,都会create一个原生 view 吗?
    2020-03-19
    1
    2
  • jianwei
    floatingActionButton: 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-08
    2
  • 无名
    iOS 平台视图中:-(NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{} 为何frame的值都是(0.0, 0.0, 0.0, 0.0),为何没有宽高?这里不应该是显示的视图大小吗?
    2020-08-14
    1
  • 星星
    这个在io.flutter.embedding.android.FlutterActivity中如何绑定呢,没有响应的方法啊
    2020-03-16
    1
    1
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部