flutter跳转自身,flutter跳转原生activity

Flutter与原生通信概述

flutter与原生通信主要有三种方式:MethodChannel、EventChannel、BasicMessageChannel,这三种方式均各有适用的场景:MethodChannel用于native与flutter的方法调用,EventChannel用于native单向的向flutter发送广播消息,BasicMessageChannel用于native与flutter之间的消息互发。

创新互联主要从事网页设计、PC网站建设(电脑版网站建设)、wap网站建设(手机版网站建设)、成都响应式网站建设公司、程序开发、网站优化、微网站、微信小程序定制开发等,凭借多年来在互联网的打拼,我们在互联网网站建设行业积累了丰富的网站设计、成都网站制作、网站设计、网络营销经验,集策划、开发、设计、营销、管理等多方位专业化运作于一体。

MethodChannel用于双方之间的方法互调,使用步骤是:

1.创建一个MethodChannel对象,传入MethodChannel名称。

2.使用setMethodHandle对对方调用自己的方法进行监听,通过回调中的MethodCall对象方法名判断、获取方法参数,并且返回调用结果。

3.使用invokeMethod来调用对方的方法,可传入方法名,方法参数,以及监听对方的回调结果。

以下是示例:

需要注意的是,MethodChannel的名称需要双方保持一致,否则就不是同一个MethodChannel了。另外这里的方法调用并不是像Java里面反射那样去先找到class示例对象再解析到相应的方法,而是将双方互发的消息包装成了MethodCall对象,拿到这个对象后通过MethodCall里面的方法名去判断要做什么操作,并不是直接就调用了自身(native或flutter)相对应的方法。具体要做什么操作、调用什么方法还是得自己去调用和实现。

EventChannel适用于native向flutter发送广播消息,只是单向的消息发送,native发,flutter收,返过来flutter并不能向native发送消息。例如native可将定位数据不断的报给flutter,或者录像数据等等,所有基于原生能力产生的数据都可以通过EventChannel进行发送。

步骤:

1.创建一个EventChannel对象,传入EventChannel名称。

2.flutter端调用receiveBroadcastStream进行广播消息注册,传入arguments参数即为广播名称,此参数是告诉native端你要接受的广播类型,判别是什么广播发送的数据。

2.native调用setStreamHandler方法进行广播消息监听,onListen回调里会有一个arguments参数,这里及为flutter注册的广播类型,若flutter端没有注册,则native端不会收到这个回调,也就无法进行消息发送。收到flutter端的广播注册后,根据arguments可判断广播类型,然后根据EventChannel.EventSink来进行消息发送,EventSink.success()即可将消息发送给flutter端。

3.flutter进行广播注册会返回一个streamSubscription类型的对象,该对象可以进行消息的停止,native可在onCancel回调里面收到。

示例如下:

BasicMessageChannel就是比较常用的消息互发,使用步骤如下:

1.创建BasicMessageChannel对象,传入BasicMessageChannel名称。还需传入编解码方式(可以自己实现),系统提供了一些列的编解码方式,后续会介绍到。

2.使用setMessageHandler方法进行消息监听,也可进行回复。

3.使用send方法进行消息发送。

无论哪种方式的消息传递,最终都是将自定义数据转化为二进制数据进行传递,flutter提供的编解码方式分为MethodCodec和MessageCodec两种,EventChannel和MethodChannel使用的就是MethodCodec,BasicMessageChannel使用的是MessageCodec。MethodCodec其实就是在MessageCodec的基础上将数据包装了一下,使其转化为MethodCall对象方便使用。

MethodCodec源码:

MethodCodec提供了两种方式:JSONMethodCodec和StandardMethodCodec,前一种就是JSON和MethodCall对象之间的互转,后一种则是根据传入的数据基本类型(String,Integer等)来进行互转。

MessageCodec则提供了四种方式,如下图,具体就不详细讲述了,看看名字就知道是怎么回事,可以直接去看源码。最常用和默认的就是StandardMessageCodec方式。

从上面的使用方式可以看出,每一种Channel在创建的时候都需要传递一个BinaryMessenger,这个接口可以在FlutterEngine里面拿到,因此需要在FlutterActivity里面实现configFlutterEngine方法里面重写这个方法。FlutterActivity在attach FlutterEngine之后就会调用这个configFlutterEngine方法,通过flutterEngine.getPlugins().add(FlutterPlugin)方法可以FlutterPlugin的回调方法里进行数据的初始化和销毁工作。如下图

这个回调方法里的FlutterPluginBinding提供了一些我们可能会用到的对象,如下:

Flutter跳转到原生iOS、Android页面

:之所以让AppDelegate继承于UINavigationControllerDelegate,并实现navigationController:willShow方法, ,所以实现代理方法对导航栏的显示做了判断。

JumpTestViewController.swift 为:

JumpChannel.kt :

SecondActivity.kt :

在AndroidManifest.xml的application中注册SecondActivity:

在res文件夹下创建一个layout文件夹,并添加activity_second.xml文件:

Demo: flutter_jumpto_native

Flutter(六)Android与Flutter混合开发(Hybird)

如果我们目前的项目是Android的,但是接下来我们希望部分页面可以使用Flutter进行开发,甚至我们希望在Native页面中嵌入FlutterUI组件,那么我们该如何实现呢?

假设你现在Android项目的目录的结构是这样的

这时候如果你想创建一个Flutter模块,使得Android模块和Flutter模块之间可以进行交互,我们可以通过Android Studio新建一个Flutter Module,具体过程是:File — New — New Module ,之后选择Flutter Module,指定Project Location的路径为

也就是说,最终你的项目结构会是这样的

接下来在Android Module的 build.gradle 文件中添加flutter依赖

先创建一个Flutter页面

这里比较重要的是 window.defaultRouteName 这个字段,这个字段可以接收从Native传递过来的参数 (下文我们会介绍原生传递参数的方法),也就是说通过这个字段我们就可以进行Flutter页面的路由的分发

我们可以直接在Android的 MainActivity 中启动一个 FlutterActivity ,这里的 initialRoute 方法中传递的参数就对应Flutter层的 window.defaultRouteName

注意:需要在 AndroidManifest.xml 注册 FlutterActivity

自己创建一个 FlutterAppActivity 继承自 FlutterActivity

在 MainActivity 中启动 FlutterAppActivity (另外别忘了在 AndroidManifest.xml 中注册 FlutterAppActivity )

两种启动方式的区别

如果单纯只是想打开一个Flutter页面,两种方式实际上基本没有太大区别,第一种方式也许还会更简单一点。但是,在Flutter开发中,我们往往还需要开发一些Native插件供Flutter调用,如果使用复写 FlutterActivity 的方式更有利于我们在 FlutterActivity 中注册我们的Native插件,所以实际开发中一般推荐使用第二种方式

扩展思考

initialRoute 从名称上看起来是Flutter提供给我们进行Native与Flutter交互的路由跳转的,但是实际上他就是一个字符串,我们不仅仅可以传递一个路由名称,有时候我们也可以通过这个参数传递一串JSON数据,然后在Flutter端进行解析,这样我们就可以通过这个参数做更多的事情

activity_main.xml

FrameLayout 用于承载Flutter组件

MainActivity.java

使用 FragmentManager 将 FlutterFragment 添加到 FrameLayout 容器中

运行结果

上半部分是原生的TextView,下半部分是Flutter的Text组件

本节主要介绍了Native和Flutter之间的页面跳转,以及同一个页面中Native与Flutter组件的组合。接下来会介绍如何编写Android插件与Flutter进行数据交互

Flutter中InheritedWidget的使用

在Tree中从上往下高效传递数据的基类widget , 定义为:abstract class InheritedWidget extends ProxyWidget

Flutter的响应式开发与React类似,数据都是自顶向下的。

假设有祖先组点A,中间经过结点B, C,然后到结点D,D需要从A中获取数据f,那按照自顶向下数据流转,f需要依次传递给B及C,最后才到C。这样开发极为不灵活,成本也比较高。所有Flutter需要有跨结点(只能是祖先后代节点,不能跨兄弟节点)高效传递数据的方案。

大体意思如下:

InheritedWidget 是在树中高效向下传递信息的基类部件;

调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例;

在 InheritedWidget 类型的控件被引用,也就是调用过 inheritFromWidgetOfExactType 方法后,当 InheritedWidget 自身状态改变时,会导致引用了 InheritedWidget 类型的子控件重构(rebuild)。

这里随便定义一个人 Person 类。

创建一个类继承 InheritedWidget,并实现 updateShouldNotify 方法。

之前说到调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例,所以此处定义一个静态的 of 方法,通过传入的 context 获取到最近的 InheriedDataWidget 实例。

1.定义数据模型

这里随便定义一个 Person 类。

2.自定义 InheritedWidget 控件类

创建一个类继承 InheritedWidget,并实现 updateShouldNotify 方法。

之前说到调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例,所以此处定义一个静态的 of 方法,通过传入的 context 获取到最近的 InheriedDataWidget 实例。

3.InheriedDataWidget 的使用

InheriedDataWidget 使用起来也很简单,它本身也是一个控件,只要在任意一个页面的子控件调用其构造方法就行,这里我们定义一个形如的 Widget 树。

WidgetA 是一个 StatefulWidget 类型的控件,可以调用 setState 刷新,如果是继承人 Stateless 类型的控件,那我们也可以通过 Stream 或者其他方式刷新数据,感兴趣的请看[什么是 Stream? Dart

WidgetA1_1 类

WidgetA1_2 类

WidgetA1_3 类

当我们点击 floatingActionButton 的时候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都会更新 Person 的信息,而且每点 floatingActionButton 一次, 当我们点击 floatingActionButton 的时候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都会更新 Person 的信息,而且每点 floatingActionButton 一次,都会输出:

如果我们试图在和 WidgetA 的同一层级的兄弟节点去访问 InheriedDataWidget 的 Person 数据,是不行的,因为父节点中并没有插入 InheriedDataWidget。

把 WidgetB 和 WidgetA 保持同一节点

这也体现了 Inheried(遗传) 这一单词的特性,遗传只存在于父子。兄弟不存在遗传的关系。

这种数据共享的方式在某些场景还是很有用的,就比如说全局主题,字体大小,字体颜色的变更,只要在 App 根层级共享出这些配置数据,然后在触发数据改变之后,所有引用到这些共享数据的地方都会刷新,这换主题,字体是不是就很轻松,事实上 Theme.of(context).primaryColor 之流就是这么干的。

以上就是有关InheritedWidget的使用。

自己也是从事Android开发5年有余了;整理了一些Android开发技术核心笔记和面经题纲,有关更多Android开发进阶技术资料、面经题纲、核心技术笔记; 想要进阶自己、拿高薪的同学请私信我回复“核心笔记”或“面试”领取!

Flutter 另一种方法实现 RouteAware 页面跳转生命周期

咳咳,先定义一个类集成 RouteObserverPageRoutedynamic

把这个类加入到 MaterialApp 属性 navigatorObservers 中

model

然后复制我的工具类

至此准备工作完成,使用也很简单


网站标题:flutter跳转自身,flutter跳转原生activity
文章网址:http://scyanting.com/article/dssechj.html