技术标签: 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
UIFlutter
提供两种方法引入,一个是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>
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部分
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
google为原生与flutter交互创建了channel渠道来实现,主要有3种,message,method,engine,目前常使用的是前2种
首先我们先定义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()
}
}
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 交互使用主要是方便实现flutter与原生的消息传递,例如初始化页面时传递token给flutter页面,或者flutter按钮点击操作传递信息回原生页面,主要用于字符串等传递,主要使用 BasicMessageChannel传递
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的设置已完成
//注册消息通道
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详解
这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示匹配很差,0表示没有任何相关性(随机序列)。(2)在待检测图像从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。(1)首先需要一个模板图像 T(子图像)和一个待检测的图像(源图像 S)这类方法利用平方差来进行匹配,最好匹配为0。匹配越差,匹配值越大。
使用两种方法对图片进行去水印
作者:lly背景在实际应用中,地图十分庞大,而我们可能只需要对地图中的某一块区域进行研究,此时,可以通过“地图裁剪”功能提取该区域的地图或数据。同时可以减小数据量,提高数据处理的效率。注意事项1.被裁剪图层可以为点、线、面、CAD 图层、文本图层或者栅格图层,不支持对网络数据、路由数据和三维数据(三维点、线、面数据集)进行裁剪。2.裁剪图层(或者绘制的裁剪区域)必须是面图层。3.裁...
#include<stdio.h>#include<Windows.h>void reverse_string(char*p){ if (*p == ‘\0’) return 0; else { reverse_string(p + 1); printf("%c...
在获取上万条微信信息时,用循环多次请求微信链接带上获取的access_token,但在运行的过程中出现这样的错误{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest"},循环过程中保存数据所用的时间也没有超过access_token的有效时间。代码如下:请问是怎么回事回复内容:在获取...
很多人在设置电脑的登录密码老是会忘了密码是什么导致开不了机。下面由学习啦小编为大家整理了电脑上设置的密码忘记了怎么办的相关方法,希望对大家有帮助!电脑上设置的密码忘记了的解决方法和步骤情况一、非超级管理员用户首先先来解释下“非超级管理员用户”,说白了就是登陆账户名不是Administrator,如果自己没有新建用户默认使用它,如果是忘记了自己新建用户名的登陆密码,此时解决办法比较简单,当然简单是有...
场景现在做的项目是同一个包,在手机上做查询业务,平板办理业务,所以就需要在手机上面是竖屏,平板上面时横屏于是在基类Activity中就有了这段代码:@Overrideprotected void onResume() { super.onResume(); if (DisplayUtil.isPad(mContext)) { setReque...
PS:OpenCV的Python imread行业imshow接口。flags:标志位,{cv2.IMREAD_COLOR,cv2.IMREAD_GRAYSCALE,cv2.IMREAD_UNCHANGED}cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道,可用-1作为实参替代。cv2.IMREAD_GRAYSCALE:读入灰度图片,可用0作为实参替代。
类似设置validateRequest="false"的方法不推荐,因为应用程序需要显式检查所有输入,不方便。 1、前端使用encodeHtml函数对字符串进行编码,例:var editor = $("textarea[name='editorValue']");$("#contents").val(encodeHtml(editor.val()));var fo...
刚学opencv的一些基本操作
介绍了灰度变换的基本概念和操作
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