摘要:前言微信的二維碼掃描用的越來越多,所以最近就想弄明白它的實現,于是找了點資料,發現都是說使用的開源庫。看多了微信的二維碼掃描,一下看這么我實在是看不慣。
前言
微信的二維碼掃描用的越來越多,所以最近就想弄明白它的實現,于是找了點資料,發現都是說使用zxing的開源庫。這是一個很強大的開源項目,引用該項目只要簡單的幾步代碼就能實現一個簡單的二維碼掃描與生成的效果。這里做點筆記記下,還不知道如何實現的也可以來學習下。
準備工作先下載zxing項目,不過推薦下載精簡版,BarCodeTest這個就足夠實現該功能了。把下載的項目添加到自己項目的依賴中,引用該項目。如何添加Module這里就不多說了相信大家都能自己解決。下面進行實現操作。
掃描二維碼因為是引用別人的開源項目,所以我們能很簡單的使用別人定義好的類來實現該功能,這里用到的主要是CaptureActivit類,當我們要掃描時跳轉到該類開啟掃描功能:
//打開掃描界面掃描條形碼或二維碼 Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class); startActivityForResult(openCameraIntent, 0);
重寫onActivityResult方法,通過TextView顯示出掃描的結果:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //處理掃描結果(在界面上顯示) if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); String scanResult = bundle.getString("result"); resultTextView.setText(scanResult); } }
這里直接通過bundle.getString("result")就可以獲取掃描的結果,因為在CaptureActivity中的handleDecode已經對其做了處理:
public void handleDecode(Result result, Bitmap barcode) { inactivityTimer.onActivity(); playBeepSoundAndVibrate(); String resultString = result.getText(); //FIXME if (resultString.equals("")) { Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show(); }else { // System.out.println("Result:"+resultString); Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putString("result", resultString); resultIntent.putExtras(bundle); this.setResult(RESULT_OK, resultIntent); } CaptureActivity.this.finish(); }
掃描的功能到這里就結束了生成二維碼
這里生成二維碼也很簡單,只是要調用該開源項目的EncodingHandler的createQRCode方法生成Bitmap對象,通過ImageView顯示出來:
try { String contentString = qrStrEditText.getText().toString(); if (!contentString.equals("")) { //根據字符串生成二維碼圖片并顯示在界面上,第二個參數為圖片的大小(450*450) Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 450); qrImgImageView.setImageBitmap(qrCodeBitmap); } else { Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show(); } } catch (WriterException e) { // TODO Auto-generated catch block e.printStackTrace(); }
是不是感覺太簡單了,沒錯就是這么簡單,其實剛開始了解的時候也驚呆了,不禁感嘆開源真是牛叉啊!界面修改
其實通過上面的實現你會發現功能是實現了,但界面真是看不過去了,感覺瞬間回到了解放前似得,有木有這種感覺。看多了微信的二維碼掃描,一下看這么low我實在是看不慣。我們可以簡單的做下修改。首先我們找到CameraManager類,在該類中我們主要是修改下掃描框的大小(原來的實在是感覺太小氣了)把相應的參數改大點就可以了,下面是我自己修改的大小:
private static final int MIN_FRAME_WIDTH = 400; private static final int MIN_FRAME_HEIGHT = 400; private static final int MAX_FRAME_WIDTH = 600; private static final int MAX_FRAME_HEIGHT = 600;
下面要該的就是添加跟微信一樣的移動激光條、四個角的簡單裝飾與文字顯示。我們要找到ViewfinderView類,在onDraw方法中做繪制的修改。首先把原來的描邊的顏色改成灰色:
paint.setColor(Color.GRAY); canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint); canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint); canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint); canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);
默認為綠色,因為下面我們要畫跟微信一樣的綠色的四個角,顏色一樣就有點不協調了。
//畫掃描框的四個裝飾角 paint.setColor(FRAME_COLOR); canvas.drawRect(frame.left, frame.top, frame.left + FRAME_WIDTH, frame.top + FRAME_HEIGHT, paint); canvas.drawRect(frame.left, frame.top, frame.left + FRAME_HEIGHT, frame.top + FRAME_WIDTH, paint); canvas.drawRect(frame.right - FRAME_WIDTH, frame.top, frame.right, frame.top + FRAME_HEIGHT, paint); canvas.drawRect(frame.right - FRAME_HEIGHT, frame.top, frame.right, frame.top + FRAME_WIDTH, paint); canvas.drawRect(frame.right - FRAME_HEIGHT, frame.bottom - FRAME_WIDTH, frame.right, frame.bottom, paint); canvas.drawRect(frame.right - FRAME_WIDTH, frame.bottom - FRAME_HEIGHT, frame.right, frame.bottom, paint); canvas.drawRect(frame.left,frame.bottom-FRAME_WIDTH,frame.left+FRAME_HEIGHT,frame.bottom,paint); canvas.drawRect(frame.left,frame.bottom-FRAME_HEIGHT,frame.left+FRAME_WIDTH,frame.bottom,paint);
這里主要的根據frame的top、left、right與bottom參數來繪制,每個角要繪制兩次。FRAME_HEIGHT與FRAME_WIDTH分別為自己設置的角的寬高。可以拿微信的對照。
下面修改激光線,把原來的激光繪制去掉添加如下代碼:
//初始化laser if (!isStart){ isStart = true; laserTop = frame.top; laserBottom = frame.bottom; } //繪制laser laserTop += LASER_SPEED;//每次的移動距離 if (laserTop >= frame.bottom){ laserTop = frame.top; } canvas.drawRect(frame.left + LASER_WIDTH, laserTop - LASER_WIDTH / 2, frame.right - LASER_WIDTH, laserTop + LASER_WIDTH / 2, paint); //更新laser實現移動 postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
至于文字的繪制也是響應的原理,找到要繪制的坐標,調用canvas.drawText就可以了,不過畫筆paint.setTextSize()單位是px(像素),這點感覺有點麻煩,在不同的分辨率的機型下字體的大小會相差很大。。有點蛋疼。希望有好的解決的方法可以告訴我。
效果圖文字我沒有調,自己可以調下。我是按我手機居中來調的,這個是768 x 1280的,文字完全變樣了。。。
其他分享:https://idisfkj.github.io/
關注文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65793.html
閱讀 3077·2021-10-27 14:16
閱讀 2885·2021-09-24 10:33
閱讀 2293·2021-09-23 11:21
閱讀 3236·2021-09-22 15:14
閱讀 824·2019-08-30 15:55
閱讀 1685·2019-08-30 15:53
閱讀 1754·2019-08-29 11:14
閱讀 2195·2019-08-28 18:11