接到一個app的改造的任務,主要是適配一款手持設備,在頁面上增加一個類似微信的二維碼掃描的喚醒按鈕,點擊之後進入掃描二維碼的頁面:
步驟如下:
1、在項目中下載QRCode的cordova插件:
ionic cordova plugin add codova-plugin-qrscanner
2、下載QRScanner插件:
npm install --save @ionic-native/qr-scanner
這裏要注意一下你下載的qr-scanner版本是什麼,就我的來說,4.0+的版本的引入和5.0+的版本引入有一些區別,導致我調試了好久才發現引入的問題;
3、創建一個掃描儀頁面,整個頁面都是拿來作掃描的界面,這個界面在調用qrscanner對象的scan方法,此方法會返回文本掃描的Observable,使用訂閱subscribe,scanner對象的調用unsubscribe將會取消訂閱;
這個頁面我是這樣做的——————
1️⃣qrscanner.html:
<ion-header>
<ion-navbar>
<ion-title>掃描二維碼</ion-title>
</ion-navbar>
</ion-header>
<ion-content [ngClass]="{'qrscanner':isShow}">
<div class="area"></div>
<div class="line"></div>
</ion-content>
<ion-footer>
<div class="warp-icon" tappable (click)="close()">
<img src="../../../assets/imgs/qrscanner/close.svg" alt="">
<span>取消</span>
</div>
<div class="warp-icon" tappable (click)="toggleLight()">
<img src="../../../assets/imgs/qrscanner/flashlight.svg" alt="">
<span>手電筒</span>
</div>
</ion-footer>
2️⃣qrscanner.ts:
import { Component, forwardRef, Inject } from '@angular/core';
import { Events, IonicPage, NavController } from 'ionic-angular';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
import { NativeService } from '../../../providers/scan/NativeService';
/**
* 掃描二維碼
* @example
this.navCtrl.push('QrscannerPage').then(() => {
this.events.subscribe('qrscanner:result', text => {
alert('掃描結果:' + text);
});
});
*/
@IonicPage()
@Component({
selector: 'page-qrscanner',
templateUrl: 'qrscanner.html',
})
export class QrscannerPage {
light: boolean = false; // 判斷閃光燈
isShow: boolean = false; // 控制顯示背景,避免切換頁面卡頓
constructor(
private navCtrl: NavController,
private nativeService: NativeService,
private events: Events,
// **如果沒有注意版本問題,引入的方式錯誤,下面的依賴會報錯:
// Error: Can't resolve all parameters for QrscannerPage: ([object Object], [object Object], [object Object], ?).
private qrScanner: QRScanner,
) { }
ionViewDidLoad() {
if (!this.nativeService.isMobile()) { // 判斷當前設備
alert('請使用真機調試');
return;
}
this.qrScanner.prepare().then((status: QRScannerStatus) => {
if (status.authorized) { // 判斷是否有攝像頭權限
let scanSub = this.qrScanner.scan().subscribe((text: string) => {
this.events.publish('qrscanner:result', text);
scanSub.unsubscribe();
this.navCtrl.pop();
});
// 打開攝像頭
this.qrScanner.show();
} else if (status.denied) {
alert('沒有攝像頭權限,請前往設置中開啓');
} else {
alert('沒有攝像頭權限,請前往設置中開啓');
}
}).catch((e: any) => console.log('調用二維碼掃描插件失敗', e));
}
ionViewWillEnter() {
// 設置掃面頁面背景透明
(window.document.querySelector('ion-app') as HTMLElement).classList.add('cameraView'); // tslint:disable-line
this.isShow = true; // 顯示背景
}
ionViewWillLeave() {
(window.document.querySelector('ion-app') as HTMLElement).classList.remove('cameraView'); // tslint:disable-line
this.qrScanner.hide(); // 需要關閉掃描,否則相機一直開着
this.qrScanner.destroy(); // 關閉
this.events.unsubscribe('qrscanner:result'); // 退出頁面取消所有訂閱,進入頁面前需訂閱
}
// 開關手電筒
toggleLight() {
this.light ? this.qrScanner.disableLight() : this.qrScanner.enableLight();
this.light = !this.light;
}
// 取消掃描
close() {
this.navCtrl.pop();
}
}
注意上面的QRScanner這個依賴,我使用的QRScanner插件的版本是5.0+的版本(5.25.0版本),在它的依賴目錄裏面qr-scanner,index.d.ts中,QRScanner這個依賴不是作爲類輸出的,所以我們應該在頁面上引用qr-scanner的ngx文件夾中的index.d.ts中輸出的QRScanner類:
3️⃣qrscanner.module.ts:
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { QrscannerPage } from './qrscanner';
import { QRScanner } from '@ionic-native/qr-scanner/ngx';
@NgModule({
declarations: [
QrscannerPage,
],
imports: [
IonicPageModule.forChild(QrscannerPage),
],
exports: [
QrscannerPage
],
providers: [
QRScanner
]
})
export class QrscannerPageModule {
}
4️⃣qrscanner.scss:
ion-app.cameraView,
ion-app.cameraView ion-content,
ion-app.cameraView .nav-decor {
background: transparent none !important;
.tabbar.show-tabbar {
opacity: 0;
}
}
page-qrscanner {
.qrscanner {
background: none;
.area {
margin-top: 30px;
width: 100%;
height: 90%;
background: url(../../../assets/imgs/qrscanner/scanner.svg) no-repeat center center;
background-size: contain;
}
.line {
left: 25%;
width: 50%;
height: 2px;
background: red;
position: absolute;
animation: myfirst 2s linear infinite alternate;
}
@keyframes myfirst {
0% {
background: red;
top: 34%;
}
25% {
background: yellow;
top: 40%;
}
50% {
background: blue;
top: 46%;
}
75% {
background: green;
top: 52%;
}
100% {
background: red;
top: 60%;
}
}
}
ion-footer {
display: flex;
justify-content: space-around;
padding: 22px;
.warp-icon {
width: 54px;
height: 54px;
background: #918c8c;;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
span {
position: absolute;
margin-top: 38px;
font-size: 12px;
color: #fff;
}
}
}
}
以上的這個組件作爲一個封裝好的頁面,可以一次封裝,到處引用。
4、注意要在app.module.ts中引入QRScanner依賴:
import { QRScanner } from '@ionic-native/qr-scanner/ngx';
providers: [
QRScanner,
.....
]
5、variables.scss:
在後面增加樣式,用於掃碼的頁面透明顯示:
ion-app.cameraView,
ion-app.cameraView ion-content,
ion-app.cameraView .nav-decor {
background: transparent none !important;
.tabbar.show-tabbar {
opacity: 0;
}
}
_____________________________________________________________________
下面開始使用上面封裝的掃碼頁面:
在需要使用的頁面上,直接跳轉到掃碼頁面上即可:
在html上增加掃碼入口按鈕:
<button ion-button (click)="showScanner()" style="width: 10px;">
<ion-icon ios="ios-qr-scanner" md="md-qr-scanner"></ion-icon>
</button>
在ts上跳轉頁面:
showScanner() {
this.navCtrl.push('QrscannerPage')
}
——————————————————————————————————————
附上scss中用到的圖片素材,自己放到自己項目的圖片文件夾中:
——————————————————————————————————————
由於廠商的設備還沒有寄到我手上,所以暫時沒有辦法調試,現在在筆記本本地調試的效果如下,頁面顯示暫時沒有辦法正常展示,大家可以作爲參考: