flutter踩坑记录(二)--基本使用及原生flutter交互篇_努力为明天的博客-程序员资料_flutter桥接原生 token

技术标签: flutter使用  

flutter踩坑记录目录

flutter踩坑记录(一)--项目准备阶段   https://blog.csdn.net/hjr365708064/article/details/95454939

flutter踩坑记录(三)-- 项目打包  https://blog.csdn.net/hjr365708064/article/details/95473183

通过上一篇的踩坑记录(一),我相信你此时已经集成flutter模块到原生项目中,也迫不及待去使用flutter和体验flutter与原生的交互(目前大多数使用场景还是要与原生集成混合开发的)

Android中创建Flutter UI

Flutter提供两种方法引入,一个是View,一个是Fragment,(目前使用我使用的view方式引用,这种方式也更灵活方法,有一个viewGroup载体就可加载flutterView)

在oncreat中添加view(下面提到的rootLayout即为布局内一个空的ConstraintLayout的viewId,使用kotlin只需要有id就可使用view)

布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"
        android:id="@+id/rootLayout"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

activity中代码文件

val flutterView = Flutter.createView(this, lifecycle, "home_page")
val layoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,
        ConstraintLayout.LayoutParams.MATCH_PARENT)
rootLayout.addView(flutterView, layoutParams)

createView方法说明:

第二个参数是Lifecycle对象,第三个参数是route(flutter页面跳转路径),这个参数Flutter端可以通过window.defaultRouteName获取

此时原生端加载flutterView载体已经搭建好,我们去看下flutter部分

dart代码的编写

import 'package:flutter/material.dart';

import 'list.dart';

 

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

// This widget is the root of your application.

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Demo',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home: MyHomePage(title: 'Flutter Demo Home Page'),

routes: {

"home_page": (context) => MyHomePage(),

},

);

}

}

此时已经实现了原生页面中加入了flutterView的页面显示,可对于我们来说还远远不够,更重要的原生与flutter交互应该是大部分原生开发者更关心的方面

参考链接 https://blog.csdn.net/weixin_33943347/article/details/91430352

Andriod 原生与flutter交互


google为原生与flutter交互创建了channel渠道来实现,主要有3种,message,method,engine,目前常使用的是前2种

method channel 实现

原生activity内代码:

首先我们先定义channel 名称

private val CHANNEL = "demo.plugin"

method  channel 交互使用主要是使用了回调方式,这一点和原生与h5交互很类似,主要可用于flutter调用原生信息,调用方法等

//从flutter中调回原生页面
        MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
            when {
                call.method == "interaction" -> {
//                    val intent = Intent([email protected],
//                            PersonalSettingActivity::class.java)
//                    startActivity(intent)
                    val id = call.arguments as Int
                    ToastUtil.show(mContext!!,"收到的id为$id")
                }
                call.method == "methodId" -> result.success(12)
                else -> result.notImplemented()
            }
        }

flutter部分大部分代码实现

class _MyHomePageState extends State<MyHomePage> {

//原生与flutter部分渠道名一定要统一

final demoPlugin = const MethodChannel('demo.plugin');

num id = 0;

@override

void initState() {

super.initState();

getMethodId();

}

 

getMethodId() async {

var id = await demoPlugin.invokeMethod('methodId');

setState(() {

this.id = id;

});

}

widget显示部分

Text('需要的id为${this.id}'),

Container(

padding: EdgeInsets.only(top: 10.0),

child: RaisedButton(

child: Text('现在是Flutter'),

onPressed: () {

demoPlugin.invokeMethod('interaction', 123);

},

),

),

方法解释说明:

call.method == "interaction"  用来从flutter给原生发送信息或者打开原生页面的实现

call.method == "methodId"   用来flutter页面初始化从原生处取所需消息

message channel 渠道实现

message channel 交互使用主要是方便实现flutter与原生的消息传递,例如初始化页面时传递token给flutter页面,或者flutter按钮点击操作传递信息回原生页面,主要用于字符串等传递,主要使用 BasicMessageChannel传递

activity部分代码

private val CHANNEL = "demo.plugin"
private var messageChannel: BasicMessageChannel<String>? =null(string是自定义的传递消息的泛型)
val flutterView = Flutter.createView(this,lifecycle,"flutter_view")
val layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT)
linearLayout.addView(flutterView,layoutParams)
/**
 * 初始化通信通道
 * 参数一:FlutterView实例对象
 * 参数二:消息通道名字(key)
 * 参数三:消息解码器(用于处理通信消息类型)
 */
messageChannel = BasicMessageChannel(flutterView,CHANNEL, StringCodec.INSTANCE)
//处理来自Flutter中发送的消息
messageChannel!!.setMessageHandler { p0, p1 ->
    //具体处理接收到的从Flutter中发送的消息 p0
    Log.e("setMessageHandler",p0)
    p1?.reply("")
}
//延时发送,确保页面初始化完成后发送数据
Handler().postDelayed({run {
    messageChannel?.send(accessToken!!)
}},2000)

此时activity对于message channel的设置已完成

dart部分代码

//注册消息通道

static const BasicMessageChannel<String> platform =

BasicMessageChannel<String>("demo.plugin", StringCodec());

String message = "测试";

widget部分代码

Column(

children: <Widget>[

Text(message),

RaisedButton(

onPressed: () {

platform.send('给原生页面发消息');

},

child: Text('给原生页面发消息'),

),

InkWell(

child: Text('获取ID'),

onTap: () {

_getPicUploadId();

},

)

],

)

具体处理messageHandler逻辑

Future<String> _handleMessage(String message) async {

setState(() {

this.message = message;

// SharePreferencesUtil().setString('token', message);

});

return "";

}

 

@override

void initState() {

super.initState();

platform.setMessageHandler(_handleMessage);

}

至此已展示两种常用消息通道的基本使用,如需更详细使用可参考Flutter Platform channel详解

链接为 https://www.jianshu.com/p/cb96d62f5042

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hjr365708064/article/details/95459151

智能推荐

OpenCV数字图像处理实战二:模板匹配(C++)_opencv模板匹配_qq_43784519的博客-程序员资料

这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示匹配很差,0表示没有任何相关性(随机序列)。(2)在待检测图像从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。(1)首先需要一个模板图像 T(子图像)和一个待检测的图像(源图像 S)这类方法利用平方差来进行匹配,最好匹配为0。匹配越差,匹配值越大。

怎么裁剪_supermapsupport的博客-程序员资料_超图软件怎么裁剪影像

作者:lly背景在实际应用中,地图十分庞大,而我们可能只需要对地图中的某一块区域进行研究,此时,可以通过“地图裁剪”功能提取该区域的地图或数据。同时可以减小数据量,提高数据处理的效率。注意事项1.被裁剪图层可以为点、线、面、CAD 图层、文本图层或者栅格图层,不支持对网络数据、路由数据和三维数据(三维点、线、面数据集)进行裁剪。2.裁剪图层(或者绘制的裁剪区域)必须是面图层。3.裁...

编写一个函数 reverse_string(char * string)(递归实现)_Vince.L的博客-程序员资料

#include&lt;stdio.h&gt;#include&lt;Windows.h&gt;void reverse_string(char*p){&nbsp;if (*p == ‘\0’)&nbsp;&nbsp;return 0;&nbsp;else&nbsp;{&nbsp;&nbsp;reverse_string(p + 1);&nbsp;&nbsp;printf("%c...

php中批量获取用户信息失败,批量获取微信用户信息,在循环中多次请求微信url链接,带上的access_token失效..._weixin_39933508的博客-程序员资料

在获取上万条微信信息时,用循环多次请求微信链接带上获取的access_token,但在运行的过程中出现这样的错误{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest"},循环过程中保存数据所用的时间也没有超过access_token的有效时间。代码如下:请问是怎么回事回复内容:在获取...

设置计算机访问权限密码忘了怎么办,电脑上设置的密码忘记了怎么办_7Nut7的博客-程序员资料

很多人在设置电脑的登录密码老是会忘了密码是什么导致开不了机。下面由学习啦小编为大家整理了电脑上设置的密码忘记了怎么办的相关方法,希望对大家有帮助!电脑上设置的密码忘记了的解决方法和步骤情况一、非超级管理员用户首先先来解释下“非超级管理员用户”,说白了就是登陆账户名不是Administrator,如果自己没有新建用户默认使用它,如果是忘记了自己新建用户名的登陆密码,此时解决办法比较简单,当然简单是有...

随便推点

android的横竖屏控制失效问题_AnnisLee的博客-程序员资料_android setrequestedorientation 无效

场景现在做的项目是同一个包,在手机上做查询业务,平板办理业务,所以就需要在手机上面是竖屏,平板上面时横屏于是在基类Activity中就有了这段代码:@Overrideprotected void onResume() { super.onResume(); if (DisplayUtil.isPad(mContext)) { setReque...

OpenCV图像处理——数字图像处理基本操作_yuesichiu的博客-程序员资料_cv2数字图像处理

PS:OpenCV的Python imread行业imshow接口。flags:标志位,{cv2.IMREAD_COLOR,cv2.IMREAD_GRAYSCALE,cv2.IMREAD_UNCHANGED}cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道,可用-1作为实参替代。cv2.IMREAD_GRAYSCALE:读入灰度图片,可用0作为实参替代。

彻底解决“从客户端中检测到有潜在危险的Request.Form值”_weixin_34005042的博客-程序员资料

类似设置validateRequest="false"的方法不推荐,因为应用程序需要显式检查所有输入,不方便。 1、前端使用encodeHtml函数对字符串进行编码,例:var editor = $("textarea[name='editorValue']");$("#contents").val(encodeHtml(editor.val()));var fo...

OpenCV数字图像处理之ROI区域的提取_gykaula的博客-程序员资料_opencv roi

OpenCV数字图像处理之ROI区域的提取利用mask(掩模)技术提取纯色背景图像ROI区域中的人和物,并将提取出来的人或物添加在其他图像上。1、实现原理先通过cv.cvtColor()函数,将原RGB彩色图像转换为hsv色彩空间的图像,然后通过cv.inRange()函数获得ROI区域的Mask,最后利用cv.bitwise()函数提取得到ROI区域。2、使用的函数简述(1) cv.cvtColor(img, cv.COLOR_BGR2HSV)函数img为要进行色彩空间转换的原图cv.COL

推荐文章

热门文章

相关标签