問(wèn)題描述:
flutter web 中使用Image控件加載二維碼圖片,在微信中打開(kāi)包含二維碼的頁(yè)面萍虽,長(zhǎng)按二維碼圖片,微信無(wú)法識(shí)別圖片中包含的二維碼
示例代碼:
class QRCodePageextends StatefulWidget {
@override
? _QRCodePageStatecreateState() =>_QRCodePageState();
}
class _QRCodePageStateextends State {
@override
Widgetbuild(BuildContext context) {
return Center(child:Image.asset("res/img/testqcode.png"),);}
}
問(wèn)題分析:
1.首先了解下微信識(shí)別二維碼的原理機(jī)制:
? ?“微信識(shí)別二維碼采用的邏輯是截屏識(shí)別,當(dāng)客戶端發(fā)現(xiàn)用戶在網(wǎng)頁(yè)的img標(biāo)簽內(nèi)進(jìn)行長(zhǎng)按操作時(shí)届榄,會(huì)立刻截屏并且啟動(dòng)二維碼識(shí)別算法。所以這里用于二維碼識(shí)別的圖片是截屏倔喂,而不是之前有人提到的img標(biāo)簽中的圖片铝条。
? ?為什么要用截屏,客戶端截屏?xí)r候席噩,可以不用考慮網(wǎng)絡(luò)傳輸?shù)纫蛩匕噻郑羁斓牡玫阶R(shí)別結(jié)果,否則就需要走一次圖片下載的邏輯悼枢,用戶長(zhǎng)按后等待的時(shí)間會(huì)加長(zhǎng)埠忘,體驗(yàn)上也失去了快感。
2.通過(guò)了解微信識(shí)別二維碼的關(guān)鍵在img標(biāo)簽,我們看下flutter web 頁(yè)面運(yùn)行起來(lái)后是否包含img標(biāo)簽
我們使用Chrome 打開(kāi)web頁(yè)面莹妒,打開(kāi)頁(yè)面檢測(cè)名船,使用控件選取工具,點(diǎn)擊頁(yè)面中的二維碼圖片动羽,查看標(biāo)簽信息.
如下圖所示:
從上面標(biāo)注的內(nèi)容包帚,可以看到頁(yè)面控件中沒(méi)有包含img控件,到這里我們的問(wèn)題就已經(jīng)很明確了运吓,問(wèn)題就是flutter 的image 控件渴邦,在dart2js轉(zhuǎn)換后不會(huì)生成img控件。
解決方案:
通過(guò)上面的分析得知拘哨,該問(wèn)題產(chǎn)生的原因是缺失img標(biāo)簽谋梭,我們需要在把圖片放置在img標(biāo)簽中,由于dart2js 無(wú)法將image控件或其它控件轉(zhuǎn)換成img標(biāo)簽倦青,所以我們需要通過(guò)html的方式添加img控件瓮床,這里需要用到HtmlElementView控件。
HtmlElementView是Flutter為我們提供了一個(gè)專門用于web的控件产镐,用于加載html 字符串隘庄、html鏈接、iframe等
1.生成圖層唯一標(biāo)識(shí)癣亚,HtmlElementView載入的每一個(gè)圖層都需要有不同的唯一標(biāo)識(shí)丑掺,如果兩次加載的圖層唯一標(biāo)識(shí)相同,控件無(wú)法正常渲染述雾。
String _divId =DateTime.now().toIso8601String();
2.創(chuàng)建并注冊(cè)html控件街州,添加img控件
initQRCode(String _divId,String imagePath,double width,double height) {
ui.platformViewRegistry.registerViewFactory(_divId, (int viewId) {
/// 二維碼圖片控件
? ImageElement imageElement =new ImageElement();
? imageElement.src = imagePath;
? imageElement.width = width.toInt();
? imageElement.height = height.toInt();
? return imageElement;
});
}
注意:當(dāng)直接使用ui.platformViewRegistry.registerViewFactory時(shí)會(huì)提示無(wú)法找到該方法,解決方案看這里:http://www.reibang.com/p/76ec2254c3af
3.使用HtmlElementView控件加載注冊(cè)的html控件
class _QRCodeWidgetStateextends State?{
/// 視圖Id
? String_divId;
? @override
? Widgetbuild(BuildContext context) {
_divId =DateTime.now().toIso8601String();
? ? initQRCode(_divId, widget.imagePath, widget.width, widget.height);
? ? return HtmlElementView(viewType:_divId);
? }
@override
? void initState() {
super.initState();
? }
@override
? void dispose() {
super.dispose();
? }
}
4.使用第二部中的方法查看是否包含img標(biāo)簽玻孟。
? ? ? 從截圖中我們可以看到唆缴,頁(yè)面中已經(jīng)包含img控件了,到這一步大家都認(rèn)為黍翎,有了img標(biāo)簽微信終于能識(shí)別圖片找那個(gè)的二維碼了面徽,但是經(jīng)過(guò)驗(yàn)證,發(fā)現(xiàn)微信雖然能識(shí)別頁(yè)面包含圖片玩敏,但是長(zhǎng)按圖片仍然無(wú)法識(shí)別圖片中包含的二維碼斗忌。因?yàn)閒lutter web 頁(yè)面默認(rèn)是支持縮放的,微信在截圖的時(shí)候并不一定能截取到完整的二維碼圖片旺聚,解決方案如下:
?在index.html中設(shè)置:初始縮放為1织阳,最大縮放值要大于1,不支持縮放砰粹。如下:
? ?<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no"/>