1. 原理
說明:項(xiàng)目中使用的是標(biāo)準(zhǔn)的掃碼槍,標(biāo)準(zhǔn)的意思就是它都不給開發(fā)文檔奸披。走的標(biāo)準(zhǔn)“輸入事件”谦秧,和外接鍵盤是一樣的鼠次。掃碼槍掃描到的條形碼每一位會(huì)觸發(fā)一次onkeydown事件。比如掃描條碼位‘1234567890’的條形碼邢笙,會(huì)連續(xù)執(zhí)行10次onkeydown事件啸如,條碼掃描到最后一位,會(huì)直接觸發(fā)Enter(標(biāo)準(zhǔn)掃描槍掃描數(shù)據(jù)會(huì)觸發(fā)KEYCODE_ENTER鍵)氮惯。
拓展:
掃碼槍的種類有藍(lán)牙组底、USB、串口等等筐骇,目前USB的掃碼槍主流的就是以下兩種:
- USB HID-KBW:支持 Android 熱插拔USB掃描槍會(huì)在有EditText時(shí)债鸡,掃描槍掃描內(nèi)容自動(dòng)輸入到編輯框了,即掃碼器會(huì)將掃描出來的內(nèi)容轉(zhuǎn)化為鍵盤事件铛纬,就是Android中KeyEvent里面對(duì)應(yīng)的常量(KeyEvent.KEYCODE_*)厌均。但是有很多輸入法兼容的問題,比如搜狗輸入法識(shí)別到HID設(shè)備時(shí)會(huì)隱藏?zé)o法彈出告唆,如果輸入法切換成中文時(shí)會(huì)輸入中文等等棺弊。
- USB 虛擬串口:通過串口的方式直接獲取原始數(shù)據(jù),不再跟輸入法產(chǎn)生沖突擒悬∧K可使用android-serialport-api連接到UsbDevice進(jìn)行通信,讀取數(shù)據(jù)懂牧;但掃碼槍設(shè)備要支持串口(掃碼槍若是USB HID則不支持串口)侈净。
2. 優(yōu)缺點(diǎn)
(1) 優(yōu)點(diǎn):
- 不需要額外供電以及價(jià)格便宜
- 即插即用:實(shí)質(zhì)其實(shí)就是相當(dāng)于設(shè)備的外接鍵盤,也就是它必須在有光標(biāo)的地方才能進(jìn)行掃碼僧凤,且是直接把掃到的內(nèi)容自動(dòng)輸入到輸入框中畜侦,并不受我們的控制
- 直接通過串口讀取流里面的數(shù)據(jù)
(2) 缺點(diǎn):需要知道每一款掃碼器的型號(hào)以獲取波特率及Android設(shè)備的串口地址。
備注:我的項(xiàng)目在實(shí)現(xiàn)獲取掃碼槍數(shù)據(jù)的過程中并未體現(xiàn)該缺點(diǎn)躯保。
3. 監(jiān)聽掃碼槍事件獲取數(shù)據(jù)
備注:掃碼槍就是 = 鍵盤 + 回車旋膳,即外接接盤。所以建個(gè)txt文本文檔或者doc隨便途事,打開验懊,然后連接掃碼槍擅羞,開始掃描,掃碼結(jié)果就會(huì)自動(dòng)填入你的文檔义图。
- 方案一:監(jiān)聽鍵盤的keydown事件(監(jiān)聽js鍵盤事件)
分析:uniapp無document對(duì)象祟滴,無法獲取keydown事件。無鍵盤事件歌溉,不支持鍵盤修飾符垄懂。 - 方案二:通過native.js調(diào)用安卓原生類庫,通過廣播方式實(shí)現(xiàn)掃碼結(jié)果的接收痛垛。參考1草慧、參考2、參考三
分析:需從廠商那里獲取到android開發(fā)文檔匙头,查看掃碼廣播標(biāo)識(shí)(意圖action)
對(duì)應(yīng)的字段漫谷。
var main,receiver,filter;
① 在過濾器中添加掃碼廣播標(biāo)識(shí)(意圖action)
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
filter = new IntentFilter();
filter.addAction("com.se4500.onDecodeComplete"); //監(jiān)聽掃描
//filter.addAction("com.zkc.scancode");//監(jiān)聽掃描
注意
:不同廠商掃碼廣播標(biāo)識(shí)action對(duì)應(yīng)的字段不一樣,這里以com.se4500.onDecodeComplete為例蹂析。
② 注冊(cè)廣播接受者BroadcastReceiver并重寫onReceive()方法
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver',{
onReceive : function(context, intent) {
plus.android.importClass(intent); //通過intent實(shí)例引入intent類舔示,方便以后的‘.’操作
/*這個(gè)se4500很坑,不同的手機(jī)或pda电抚,這個(gè)值就不一樣惕稻,要具體去查硬件api*/
var code = intent.getStringExtra("se4500");
// var code = intent.getStringExtra("code");
console.log('條碼:',code);
}});
注意
:獲取掃碼數(shù)據(jù)時(shí),此處key為se4500僅為示例蝙叛,不同手機(jī)或pda俺祠,這個(gè)值不一樣,具體要去查硬件api借帘。
③ 注冊(cè)監(jiān)聽
main = plus.android.runtimeMainActivity();//獲取activity
main.registerReceiver(receiver,filter); //注冊(cè)監(jiān)聽
④ 注銷監(jiān)聽
main.unregisterReceiver(receiver); //取消監(jiān)聽
- 方案三:使用 5+ 的api監(jiān)聽鍵盤事件
分析:H5 和小程序不能監(jiān)聽鍵盤事件蜘渣,但是app端可通過使用 5+ 的api監(jiān)聽鍵盤事件。經(jīng)測(cè)試肺然,app端使用 5+ 的api未能監(jiān)聽到鍵盤事件蔫缸。
這種方案應(yīng)該是最合適的,但是測(cè)試未成功际起,這里僅提供一個(gè)思路拾碌,可能我的實(shí)現(xiàn)方法錯(cuò)了,虛心求教有思路的小伙伴加叁。
<template>
<view>
plus監(jiān)聽原生擴(kuò)展事件:掃碼結(jié)果{{resultValue}}
</view>
</template>
<script>
var _self;
export default {
data() {
return {
resultValue:""
}
},
methods: {
},
onLoad:function(){
_self = this;
// #ifdef APP-PLUS
/* plus.key.addEventListener('backbutton',function(KeyEvent){
console.log("點(diǎn)擊了返回鍵:" + JSON.stringify(KeyEvent));
console.log("點(diǎn)擊了返回鍵:" + KeyEvent.keyCode);
}); */
plus.key.addEventListener('keydown',function(KeyEvent){
console.log("按下了鍵:" + JSON.stringify(KeyEvent));
console.log("按下了鍵:" + KeyEvent.keyCode);
if(KeyEvent.keyCode == 9){
//plus.nativeUI.toast("Tab結(jié)束符");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 10){
//plus.nativeUI.toast("換行結(jié)束符");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 13){
//plus.nativeUI.toast("按下了回車鍵");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 48){
_self.resultValue = _self.resultValue + "0";
}else if(KeyEvent.keyCode == 49){
_self.resultValue = _self.resultValue + "1";
}else if(KeyEvent.keyCode == 50){
_self.resultValue = _self.resultValue + "2";
}else if(KeyEvent.keyCode == 51){
_self.resultValue = _self.resultValue + "3";
}else if(KeyEvent.keyCode == 52){
_self.resultValue = _self.resultValue + "4";
}else if(KeyEvent.keyCode == 53){
_self.resultValue = _self.resultValue + "5";
}else if(KeyEvent.keyCode == 54){
_self.resultValue = _self.resultValue + "6";
}else if(KeyEvent.keyCode == 55){
_self.resultValue = _self.resultValue + "7";
}else if(KeyEvent.keyCode == 56){
_self.resultValue = _self.resultValue + "8";
}else if(KeyEvent.keyCode == 57){
_self.resultValue = _self.resultValue + "9";
}else if(KeyEvent.keyCode == 65){
_self.resultValue = _self.resultValue + "A";
}else if(KeyEvent.keyCode == 66){
_self.resultValue = _self.resultValue + "B";
}else if(KeyEvent.keyCode == 67){
_self.resultValue = _self.resultValue + "C";
}else if(KeyEvent.keyCode == 68){
_self.resultValue = _self.resultValue + "D";
}else if(KeyEvent.keyCode == 69){
_self.resultValue = _self.resultValue + "E";
}else if(KeyEvent.keyCode == 70){
_self.resultValue = _self.resultValue + "F";
}else if(KeyEvent.keyCode == 71){
_self.resultValue = _self.resultValue + "G";
}else if(KeyEvent.keyCode == 72){
_self.resultValue = _self.resultValue + "H";
}else if(KeyEvent.keyCode == 73){
_self.resultValue = _self.resultValue + "I";
}else if(KeyEvent.keyCode == 74){
_self.resultValue = _self.resultValue + "J";
}else if(KeyEvent.keyCode ==75){
_self.resultValue = _self.resultValue + "K";
}else if(KeyEvent.keyCode == 76){
_self.resultValue = _self.resultValue + "L";
}else if(KeyEvent.keyCode == 77){
_self.resultValue = _self.resultValue + "M";
}else if(KeyEvent.keyCode == 78){
_self.resultValue = _self.resultValue + "N";
}else if(KeyEvent.keyCode == 79){
_self.resultValue = _self.resultValue + "O";
}else if(KeyEvent.keyCode == 80){
_self.resultValue = _self.resultValue + "P";
}else if(KeyEvent.keyCode == 81){
_self.resultValue = _self.resultValue + "Q";
}else if(KeyEvent.keyCode == 82){
_self.resultValue = _self.resultValue + "R";
}else if(KeyEvent.keyCode == 83){
_self.resultValue = _self.resultValue + "S";
}else if(KeyEvent.keyCode == 84){
_self.resultValue = _self.resultValue + "T";
}else if(KeyEvent.keyCode == 85){
_self.resultValue = _self.resultValue + "U";
}else if(KeyEvent.keyCode == 86){
_self.resultValue = _self.resultValue + "V";
}else if(KeyEvent.keyCode == 87){
_self.resultValue = _self.resultValue + "W";
}else if(KeyEvent.keyCode == 88){
_self.resultValue = _self.resultValue + "X";
}else if(KeyEvent.keyCode == 89){
_self.resultValue = _self.resultValue + "Y";
}else if(KeyEvent.keyCode == 96){
_self.resultValue = _self.resultValue + "0";
}else if(KeyEvent.keyCode == 97){
_self.resultValue = _self.resultValue + "1";
}else if(KeyEvent.keyCode == 98){
_self.resultValue = _self.resultValue + "2";
}else if(KeyEvent.keyCode == 99){
_self.resultValue = _self.resultValue + "3";
}else if(KeyEvent.keyCode == 100){
_self.resultValue = _self.resultValue + "4";
}else if(KeyEvent.keyCode == 101){
_self.resultValue = _self.resultValue + "5";
}else if(KeyEvent.keyCode == 102){
_self.resultValue = _self.resultValue + "6";
}else if(KeyEvent.keyCode == 103){
_self.resultValue = _self.resultValue + "7";
}else if(KeyEvent.keyCode == 104){
_self.resultValue = _self.resultValue + "8";
}else if(KeyEvent.keyCode == 105){
_self.resultValue = _self.resultValue + "9";
}else if(KeyEvent.keyCode == 108){
//plus.nativeUI.toast("按下了回車鍵");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "0";
}else{
_self.resultValue = _self.resultValue + "y";
}
});
/* plus.key.addEventListener('keyup',function(KeyEvent){
console.log("松開了鍵:" + JSON.stringify(KeyEvent));
console.log("松開了鍵:" + KeyEvent.keyCode);
}); */
// #endif
},
}
</script>
<style>
</style>
監(jiān)聽設(shè)備鍵盤事件可參考:監(jiān)聽事件(系統(tǒng)事件+設(shè)備按鍵事件+自定義事件)倦沧。
- 方案四:參考原生Android外接USB掃碼槍,生成插件在uniapp中使用它匕。
分析:原生實(shí)現(xiàn)中是通過攔截dispatchKeyEvent(KeyEvent event)方法來自己處理鍵盤的輸入事件。是否能封裝成插件尚在研究中窖认。 - 方案五:使用 input 輸入框控件來接收
分析:輸入框可直接接收掃碼槍數(shù)據(jù)
方案:主要通過使用 input 的 @input 和 @confirm 事件來實(shí)現(xiàn)
備注:頁面其實(shí)并不需要顯示input控件豫柬,這里只作為接受數(shù)據(jù)的作用告希,所以盡可能在界面中隱藏該控件,從而達(dá)到既不影響用戶體驗(yàn)又能實(shí)現(xiàn)我們的功能
<input v-if="isUseScanGun" class="jk-footer" style="width: 1px;" :value="inputValue" :focus="isFocus" maxlength="-1"
@input="onInput" @focus="onFocus" @blur="onBlur" @confirm="onConfirm"/>
說明:具體實(shí)現(xiàn)過程中有一些細(xì)節(jié)問題需要處理烧给,詳情見下問題匯總
燕偶。
4. 問題匯總
4.1 失焦導(dǎo)致無法獲取掃碼數(shù)據(jù)
說明:輸入框聚焦后掃碼槍才可以把內(nèi)容輸出到輸入框中,失去焦點(diǎn)將導(dǎo)致不能獲取到掃碼數(shù)據(jù)础嫡,或者說是需手動(dòng)聚焦后才能獲取到掃碼數(shù)據(jù)指么。
(1) 失焦描述1:雖然設(shè)置了輸入框的聚焦屬性,掃碼一次后就會(huì)失去焦點(diǎn)
解決方案:輸入框失焦時(shí)重新在 @blur 事件中重新設(shè)置焦點(diǎn)
注意:此時(shí)需在輸入事件中設(shè)置焦點(diǎn)屬性為false榴鼎,之后 @blur 事件會(huì)自動(dòng)被調(diào)用伯诬,從而獲取到焦點(diǎn)。
onInput:function(e){
console.log("鍵盤輸入:" + e.detail.value);
_self.isFocus = false;
},
onFocus:function(){
console.log("輸入框聚焦");
},
onBlur:function(){
console.log("輸入框失去焦點(diǎn)");
_self.isFocus = true;
},
(2) 失焦描述2:點(diǎn)擊界面上除輸入框的其他位置巫财,也會(huì)導(dǎo)致輸入框失去焦點(diǎn)
解決方案:給整個(gè)頁面的根節(jié)點(diǎn)設(shè)置點(diǎn)擊事件盗似,重新獲取焦點(diǎn)。
注意:此時(shí)需設(shè)置焦點(diǎn)屬性為false平项,之后 @blur 事件會(huì)自動(dòng)被調(diào)用赫舒,從而獲取到焦點(diǎn)。
<template>
<view class="uni-flex uni-column" style="height: 100%;" @tap="setFocus()">
<view class="uni-flex uni-row jk-bg-blue uni-center" style="height: 12%;">
<input class="jk-footer" style="width: 1px;" :value="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/>
</view>
<view class="uni-flex" style="height: 88%;">
<view class="uni-flex justify-center align-center uni-column" style="width: 100%;height: 100%;">
</view>
</view>
</view>
</template>
setFocus:function(){
console.log("setFocus-1: " + _self.isFocus + "");
_self.isFocus = false;
console.log("setFocus-2: " + _self.isFocus + "");
},
備注
:經(jīng)驗(yàn)證闽瓢,還需在manifest.json配置文件關(guān)閉沉浸式
接癌,否則無法重新獲取焦點(diǎn)(剛好項(xiàng)目之前因需去掉原生導(dǎo)航故關(guān)閉了沉浸式,所以開始的沒發(fā)現(xiàn)需關(guān)閉沉浸式才能重新聚焦的問題)扣讼。原因未知扔涧,望知道的小伙伴告知一下。
/* 5+App特有相關(guān) */
"app-plus": {
"statusbar" : {
"immersed" : false //關(guān)閉沉浸式:解決去掉原生導(dǎo)航后届谈,主內(nèi)容頂?shù)綘顟B(tài)欄的問題;掃碼槍-輸入框聚焦問題(原因未知)
},
},
拓展:窗體默認(rèn)是沉浸式(即全屏可寫內(nèi)容)枯夜。若不啟用原生導(dǎo)航,手機(jī)頂部狀態(tài)欄區(qū)域會(huì)被頁面內(nèi)容覆蓋艰山;而系統(tǒng)導(dǎo)航欄會(huì)自動(dòng)處理狀態(tài)欄高度占位問題湖雹,不會(huì)出現(xiàn)手機(jī)頂部狀態(tài)欄區(qū)域被頁面內(nèi)容覆蓋的問題。參考自定義導(dǎo)航欄使用注意曙搬。
4.2 聚集導(dǎo)致屏幕彈出軟鍵盤問題
描述:連接掃碼槍后摔吏,每次聚焦操作都會(huì)引起頁面彈出軟鍵盤
嘗試:使用官網(wǎng)的隱藏軟鍵盤api并不能完全禁用軟鍵盤
onFocus:function(){
console.log("輸入框聚焦");
// 并不能完全禁用軟鍵盤
setTimeout(function(){
uni.hideKeyboard();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤,如果軟鍵盤沒有顯示則不做任何操作
// plus.key.hideSoftKeybord();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤纵装,如果軟鍵盤沒有顯示則不做任何操作
},250);
},
分析:系統(tǒng)設(shè)置中征讲,連接到實(shí)體鍵盤時(shí),虛擬鍵盤默認(rèn)在屏幕上保持顯示狀態(tài)
解決方案:設(shè)置當(dāng)連接到實(shí)體鍵盤時(shí)橡娄,關(guān)閉虛擬鍵盤(無實(shí)體鍵盤時(shí)才會(huì)彈出軟鍵盤)
步驟:設(shè)置 -> 語言和輸入法 -> 實(shí)體鍵盤 -> 關(guān)閉
顯示虛擬鍵盤
說明:這種系統(tǒng)設(shè)置的方案诗箍,僅能解決在外接設(shè)備的情況下禁用軟鍵盤,但是在沒有外接設(shè)備的情況下挽唉,輸入框聚焦還是會(huì)彈出軟鍵盤滤祖,用戶體驗(yàn)不好筷狼。
備注
:已找到解決軟鍵盤彈出問題的辦法,并替代上面的系統(tǒng)設(shè)置的方案匠童。
4.3 輸入法默認(rèn)為中文導(dǎo)致掃碼數(shù)據(jù)亂碼問題
說明:系統(tǒng)默認(rèn)輸入法是谷歌拼音輸入法(中文輸入法)埂材,導(dǎo)致掃碼掃出來中文,掃碼數(shù)據(jù)不對(duì)
解決方案:切換輸入法為英文輸入法汤求。
步驟:設(shè)置 -> 語言和輸入法 -> 虛擬鍵盤 -> 管理鍵盤 -> 打開
Android鍵盤(英文輸入法)
注意:雖然系統(tǒng)設(shè)置為英文輸入法俏险,但是若在登錄輸入時(shí)(或其他情況的輸入)軟鍵盤需要切換為中文進(jìn)行手動(dòng)輸入,仍會(huì)導(dǎo)致之后的掃碼亂碼扬绪。解決辦法就是輸入后軟鍵盤再切換為英文竖独。
4.4 字符截取問題
說明:每次掃碼數(shù)據(jù)都會(huì)拼接到輸入框中(輸入框默認(rèn)最大輸入長(zhǎng)度maxlength為140),但是我們只需要每次的掃碼數(shù)據(jù)勒奇。
解決方案1(雙向綁定未成功):使用雙向綁定预鬓,并監(jiān)聽每次掃碼的完成事件 @confirm,獲取當(dāng)次掃碼數(shù)據(jù)后清空輸入框數(shù)據(jù)赊颠。
分析:在輸入完成事件中清空輸入框?qū)?dǎo)致下次掃碼獲取到錯(cuò)誤數(shù)據(jù)格二,可能和輸入框的輸入事件@input 是一個(gè)字符一個(gè)字符讀取有關(guān)。
解決方案2(掃碼位數(shù)有局限性):設(shè)置不限制輸入框的最大長(zhǎng)度(maxlength = -1)竣蹦,在輸入完成事件中截取最后約定的位數(shù)作為掃碼結(jié)果顶猜。
分析:所要掃的有效二維碼位數(shù)已固定。
onConfirm:function(e){
console.log("點(diǎn)擊完成按鈕");
var str = e.detail.value;
var result = str.substring(str.length-13);//截取后13位
uni.showToast({
title: result
});
},
解決方案3(成功截取每次掃碼結(jié)果):通過當(dāng)前掃碼輸入框字符串減去上次掃碼輸入框字符串痘括,獲取到每次掃碼結(jié)果
data() {
return {
lastInputValue:"",
}
},
methods: {
onConfirm:function(e){
console.log("點(diǎn)擊完成按鈕");
var currentInputValue = e.detail.value;
var newValue = "";
if(_self.lastInputValue == ""){
newValue = currentInputValue;
}else{
//newValue = currentInputValue.replace(_self.lastInputValue,"");
newValue = currentInputValue.substring(_self.lastInputValue.length);
}
_self.lastInputValue = currentInputValue;
console.log("掃碼結(jié)果:" + newValue);
uni.showToast({
title: newValue
});
},
},
4.5 應(yīng)用重啟問題
關(guān)注帖子:在APP上接入U(xiǎn)SB掃描槍到導(dǎo)致重啟 (UNI-APP)
描述: 當(dāng)應(yīng)用打開時(shí)长窄,插拔鍵盤或掃碼槍會(huì)導(dǎo)致應(yīng)用重啟,連接掃碼槍時(shí)掃碼槍恢復(fù)出廠設(shè)置也會(huì)導(dǎo)致應(yīng)用重啟
分析:可能是檢測(cè)到鍵盤類型改變引起的纲菌,類似android中屏幕旋轉(zhuǎn)導(dǎo)致activity銷毀又重建
解決方案:先接線挠日,后打開應(yīng)用
注意:接線時(shí),若轉(zhuǎn)接頭和平板連接后再連接掃碼槍翰舌,無法給掃碼槍供電淹遵;正確的接線順序?yàn)檎痃裕D(zhuǎn)接頭和掃碼槍連接后再連接平板该抒。
備注
:該方案僅能規(guī)避連接掃碼槍時(shí)應(yīng)用重啟問題窿祥,尚未找到解決斷開掃碼槍時(shí)應(yīng)用重啟問題的方案。
更新HbuilderX版本后問題解決庇麦,經(jīng)查證2.4.1.20191114版本修復(fù)了該問題计技。
2.4.1.20191114版本解決插拔重啟問題.png
拓展:熱插拔
備注
:完整代碼示例
<template>
<view class="uni-flex uni-column" style="height: 100%;" @tap="setFocus()">
<view class="uni-flex uni-row uni-bg-blue uni-center" style="height: 12%;">
<!-- <input style="width: 1px;font-size: 15px;align-self: center;" v-model="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/> -->
<input style="width: 1px;font-size: 15px;align-self: center;" :value="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/>
</view>
<view class="uni-flex" style="height: 88%;">
<view class="uni-flex justify-center align-center uni-column" style="width: 100%;height: 100%;">
</view>
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
isFocus:true,
inputValue:"",
lastInputValue:"",
}
},
methods: {
setFocus:function(){
console.log("setFocus-1: " + _self.isFocus + "");
_self.isFocus = false;
console.log("setFocus-2: " + _self.isFocus + "");
},
input:function(e){
console.log("鍵盤輸入:" + e.detail.value);
_self.isFocus = false;
},
focus:function(){
console.log("輸入框聚焦:" + _self.isFocus);
// 并不能完全禁用軟鍵盤
setTimeout(function(){
uni.hideKeyboard();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤,如果軟鍵盤沒有顯示則不做任何操作
// plus.key.hideSoftKeybord();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤山橄,如果軟鍵盤沒有顯示則不做任何操作
},250);
},
blur:function(){
console.log("輸入框失去焦點(diǎn):" + _self.isFocus);
_self.isFocus = true;
},
confirm:function(e){
console.log("點(diǎn)擊完成按鈕");
//(1)雙向綁定來獲取掃碼結(jié)果:未成功
/* var ticketNo = _self.inputValue;
_self.inputValue = "";
uni.showModal({
title: ticketNo,
content: _self.inputValue + "h"
}); */
//(2)截取掃碼結(jié)果:掃碼位數(shù)固定垮媒,有局限性
/* var str = e.detail.value;
var result = str.substring(str.length-13);//截取后13位
console.log("掃碼結(jié)果:" + newValue);
uni.showToast({
title: result
}); */
//(3)截取每次掃碼結(jié)果:成功
var currentInputValue = e.detail.value;
var newValue = "";
if(_self.lastInputValue == ""){
newValue = currentInputValue;
}else{
//newValue = currentInputValue.replace(_self.lastInputValue,"");
newValue = currentInputValue.substring(_self.lastInputValue.length);
}
_self.lastInputValue = currentInputValue;
console.log("掃碼結(jié)果:" + newValue);
uni.showToast({
title: newValue
});
},
},
onLoad:function(){
_self = this;
}
}
</script>
<style>
</style>
5. 使用插件—外接鍵盤掃描槍監(jiān)聽獲取輸入內(nèi)容
(1) 在uniapp插件市場(chǎng)購買插件并綁定項(xiàng)目
(2) 在HBuilderX里找到項(xiàng)目,在manifest的app原生插件配置中勾選模塊
(3) 在代碼中引用插件并調(diào)用插件功能
<template>
<view>
<view class="c-hint margin-l-r" style="margin-top: 10rpx;margin-bottom: 50rpx;color: #ff0000;font-size: 24rpx;">Tips:返回結(jié)果在頁尾打印展示。先點(diǎn)擊設(shè)置監(jiān)聽涣澡,按下數(shù)組鍵
1 或者字母鍵 a贱呐,頁面會(huì)打印返回?cái)?shù)據(jù)丧诺,供查看數(shù)據(jù)結(jié)構(gòu)入桂。輸入完成,點(diǎn)擊 Enter 鍵驳阎,頁面會(huì)顯示拼接結(jié)果抗愁。</view>
<view class="c-hint margin-l-r" style="margin-top: 30rpx;">tag 字段,不用理會(huì)呵晚,固定 1 就好</view>
<input v-model="tag" class="margin-l-r" placeholder="請(qǐng)輸入" />
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn1()">設(shè)置監(jiān)聽</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn2()">取消某個(gè)監(jiān)聽</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn3()">獲取所有監(jiān)聽的tag</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn4()">取消所有監(jiān)聽</button>
</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">以下打印監(jiān)聽內(nèi)容蜘腌。</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">拼接結(jié)果:{{resultStrFinal}}</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;margin-bottom: 30rpx;width: 700rpx;word-break:break-all;">{{resultStr}}</view>
</view>
</template>
<script>
var longyoungKeyEventListen;
var preKeyCode = '';
var allKeyCodeTemp = '';
var KEY_MAP = {
"KEYCODE_GRAVE": {
"normalChar": "`",
"shiftChar": "~"
},
"KEYCODE_0": {
"normalChar": "0",
"shiftChar": ")"
},
"KEYCODE_1": {
"normalChar": "1",
"shiftChar": "!"
},
"KEYCODE_2": {
"normalChar": "2",
"shiftChar": "@"
},
"KEYCODE_3": {
"normalChar": "3",
"shiftChar": "#"
},
"KEYCODE_4": {
"normalChar": "4",
"shiftChar": "$"
},
"KEYCODE_5": {
"normalChar": "5",
"shiftChar": "%"
},
"KEYCODE_6": {
"normalChar": "6",
"shiftChar": "^"
},
"KEYCODE_7": {
"normalChar": "7",
"shiftChar": "&"
},
"KEYCODE_8": {
"normalChar": "8",
"shiftChar": "*"
},
"KEYCODE_9": {
"normalChar": "9",
"shiftChar": "("
},
"KEYCODE_MINUS": {
"normalChar": "-",
"shiftChar": "_"
},
"KEYCODE_EQUALS": {
"normalChar": "=",
"shiftChar": "+"
},
"KEYCODE_LEFT_BRACKET": {
"normalChar": "[",
"shiftChar": "{"
},
"KEYCODE_RIGHT_BRACKET": {
"normalChar": "]",
"shiftChar": "}"
},
"KEYCODE_BACKSLASH": {
"normalChar": "\\",
"shiftChar": "|"
},
"KEYCODE_SEMICOLON": {
"normalChar": ";",
"shiftChar": ":"
},
"KEYCODE_APOSTROPHE": {
"normalChar": "'",
"shiftChar": "\""
},
"KEYCODE_COMMA": {
"normalChar": ",",
"shiftChar": "<"
},
"KEYCODE_PERIOD": {
"normalChar": ".",
"shiftChar": ">"
},
"KEYCODE_SLASH": {
"normalChar": "/",
"shiftChar": "?"
},
"KEYCODE_A": {
"normalChar": "a",
"shiftChar": "A"
},
"KEYCODE_B": {
"normalChar": "b",
"shiftChar": "B"
},
"KEYCODE_C": {
"normalChar": "c",
"shiftChar": "C"
},
"KEYCODE_D": {
"normalChar": "d",
"shiftChar": "D"
},
"KEYCODE_E": {
"normalChar": "e",
"shiftChar": "E"
},
"KEYCODE_F": {
"normalChar": "f",
"shiftChar": "F"
},
"KEYCODE_G": {
"normalChar": "g",
"shiftChar": "G"
},
"KEYCODE_H": {
"normalChar": "h",
"shiftChar": "H"
},
"KEYCODE_I": {
"normalChar": "i",
"shiftChar": "I"
},
"KEYCODE_J": {
"normalChar": "j",
"shiftChar": "J"
},
"KEYCODE_K": {
"normalChar": "k",
"shiftChar": "K"
},
"KEYCODE_L": {
"normalChar": "l",
"shiftChar": "L"
},
"KEYCODE_M": {
"normalChar": "m",
"shiftChar": "M"
},
"KEYCODE_N": {
"normalChar": "n",
"shiftChar": "N"
},
"KEYCODE_O": {
"normalChar": "o",
"shiftChar": "O"
},
"KEYCODE_P": {
"normalChar": "p",
"shiftChar": "P"
},
"KEYCODE_Q": {
"normalChar": "q",
"shiftChar": "Q"
},
"KEYCODE_R": {
"normalChar": "r",
"shiftChar": "R"
},
"KEYCODE_S": {
"normalChar": "s",
"shiftChar": "S"
},
"KEYCODE_T": {
"normalChar": "t",
"shiftChar": "T"
},
"KEYCODE_U": {
"normalChar": "u",
"shiftChar": "U"
},
"KEYCODE_V": {
"normalChar": "v",
"shiftChar": "V"
},
"KEYCODE_W": {
"normalChar": "w",
"shiftChar": "W"
},
"KEYCODE_X": {
"normalChar": "x",
"shiftChar": "X"
},
"KEYCODE_Y": {
"normalChar": "y",
"shiftChar": "Y"
},
"KEYCODE_Z": {
"normalChar": "z",
"shiftChar": "Z"
}
};
export default {
data() {
return {
resultStr: "",
tag: "1", //不必理會(huì),固定 1 就好
resultStrFinal: ""
}
},
onLoad() {
let that = this;
// #ifdef APP-PLUS
//引用插件
longyoungKeyEventListen = uni.requireNativePlugin('longyoung-KeyEventListen');
// //設(shè)置監(jiān)聽饵隙,可設(shè)置多個(gè)撮珠,回調(diào)按 tag 區(qū)分哪個(gè)監(jiān)聽返回。
// longyoungKeyEventListen.setOnKeyEventListenerLy({
// tag: that.tag
// }, result => {
// console.log('lygg.result=' + JSON.stringify(result));
// if (result && result.return_code == 'SUCCESS') {
// if (result.return_type == 'dataBack') {//return_type=dataBack是返回?cái)?shù)據(jù)標(biāo)識(shí)金矛,返回的數(shù)據(jù)在此獲取
// //頁面只顯示1芯急,供查看數(shù)據(jù)結(jié)構(gòu)
// if (result.keyCode == 'KEYCODE_1') {
// that.resultStr += '\n' + JSON.stringify(result) + '\n';
// }
// uni.showToast({
// title: '成功,' + JSON.stringify(result)
// });
// }
// }
// });
// #endif
},
onUnload() {
let that = this;
// #ifdef APP-PLUS
if (longyoungKeyEventListen) {
//取消所有監(jiān)聽
longyoungKeyEventListen.disableAllOnKeyEventListenerLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
}
// #endif
},
methods: {
onBtn1() {
let that = this;
//設(shè)置監(jiān)聽,可設(shè)置多個(gè)驶俊,回調(diào)按 tag 區(qū)分哪個(gè)監(jiān)聽返回娶耍。
longyoungKeyEventListen.setOnKeyEventListenerLy({
tag: that.tag //不必理會(huì),固定 1 就好
}, result => {
console.log('lygg.result=' + JSON.stringify(result));
if (!result.keyCode) {
that.resultStr += '\n' + JSON.stringify(result) + '\n';
}
if (result && result.return_code == 'SUCCESS') {
if (result.return_type == 'dataBack') { //return_type=dataBack是返回?cái)?shù)據(jù)標(biāo)識(shí)饼酿,返回的數(shù)據(jù)在此獲取
//頁面只顯示1和a榕酒,供查看數(shù)據(jù)結(jié)構(gòu)
if (result.keyCode == 'KEYCODE_1' || result.keyCode == 'KEYCODE_A') {
that.resultStr += '\n' + JSON.stringify(result) + '\n';
}
that.handleData(result);
}
}
});
},
onBtn2() {
let that = this;
//取消某個(gè) tag 監(jiān)聽
longyoungKeyEventListen.disableOnKeyEventListenerLy({
tag: that.tag //不必理會(huì),固定 1 就好
}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
onBtn3() {
let that = this;
//獲取所有監(jiān)聽的tag
longyoungKeyEventListen.getAllKeyEventListenerTagLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
onBtn4() {
let that = this;
//取消所有監(jiān)聽
longyoungKeyEventListen.disableAllOnKeyEventListenerLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
handleData(result) {
let that = this;
console.log('lygg.handleData=' + JSON.stringify(result));
if (result.return_type == 'dataBack') {
if (result.action == 'ACTION_UP') { //只取彈起事件
let keyCode = result.keyCode;
if (keyCode == 'KEYCODE_ENTER') { //掃碼結(jié)束
that.resultStrFinal = allKeyCodeTemp; //最終拼接的字符串賦值
allKeyCodeTemp = '';
preKeyCode = '';
} else if (keyCode == 'KEYCODE_SHIFT_LEFT' || keyCode == 'KEYCODE_SHIFT_RIGHT') { //轉(zhuǎn)換鍵
preKeyCode = 'KEYCODE_SHIFT_RIGHT';
} else {
if (preKeyCode == 'KEYCODE_SHIFT_RIGHT') { //轉(zhuǎn)換鍵故俐,拿大寫
if (keyCode && KEY_MAP[keyCode]) {
allKeyCodeTemp += KEY_MAP[keyCode].shiftChar;
}
} else {
if (keyCode && KEY_MAP[keyCode]) {
allKeyCodeTemp += KEY_MAP[keyCode].normalChar;
}
}
preKeyCode = '';
}
}
}
}
}
}
</script>
<style>
.content {
width: 100%;
/* padding: 20rpx; */
}
button {
margin-top: 30rpx;
margin-bottom: 30rpx;
}
.button-sp-area {
margin: 0 auto;
width: 60%;
}
.c-hint {
color: #808080;
}
.margin-l-r {
margin-left: 20rpx;
margin-right: 20rpx;
}
.uni-list-cell {
justify-content: flex-start
}
/* 列表 */
.uni-list {
background-color: #FFFFFF;
position: relative;
width: 100%;
display: flex;
flex-direction: column;
}
.uni-list:after {
position: absolute;
z-index: 10;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list::before {
position: absolute;
z-index: 10;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell {
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.uni-list-cell-hover {
background-color: #eee;
}
.uni-list-cell-pd {
padding: 22upx 30upx;
}
.uni-list-cell-left {
font-size: 28upx;
padding: 0 30upx;
}
.uni-list-cell-db,
.uni-list-cell-right {
flex: 1;
}
.uni-list-cell::after {
position: absolute;
z-index: 3;
right: 0;
bottom: 0;
left: 30upx;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list .uni-list-cell:last-child::after {
height: 0upx;
}
.uni-list-cell-last.uni-list-cell::after {
height: 0upx;
}
.uni-list-cell-divider {
position: relative;
display: flex;
color: #999;
background-color: #f7f7f7;
padding: 15upx 20upx;
}
.uni-list-cell-divider::before {
position: absolute;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell-divider::after {
position: absolute;
right: 0;
bottom: 0;
left: 0upx;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell-navigate {
font-size: 30upx;
padding: 22upx 30upx;
line-height: 48upx;
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
flex: 1;
justify-content: space-between;
align-items: center;
}
.uni-list-cell-navigate {
padding-right: 36upx;
}
.uni-navigate-badge {
padding-right: 50upx;
}
.uni-list-cell-navigate.uni-navigate-right:after {
font-family: uniicons;
content: '\e583';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-list-cell-navigate.uni-navigate-bottom:after {
font-family: uniicons;
content: '\e581';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-list-cell-navigate.uni-navigate-bottom.uni-active::after {
font-family: uniicons;
content: '\e580';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-collapse.uni-list-cell {
flex-direction: column;
}
.uni-list-cell-navigate.uni-active {
background: #eee;
}
.uni-list.uni-collapse {
box-sizing: border-box;
height: 0;
overflow: hidden;
}
.uni-collapse .uni-list-cell {
padding-left: 20upx;
}
.uni-collapse .uni-list-cell::after {
left: 52upx;
}
.uni-list.uni-active {
height: auto;
}
/*換行*/
.text-wrapper {
white-space: pre-wrap;
}
</style>
(4) 重新制作自定義基座想鹰,然后選擇自定義基座運(yùn)行調(diào)試
(5) 開發(fā)完畢后正式云打包