Android 動態載入二維碼檢視生成快照
阿新 • • 發佈:2019-01-05
1.需求背景
需要實現一個動態載入但不顯示出來的檢視,且該檢視上有個動態生成的二維碼,最後用其去生成一張快照(也就是圖片)。
(常見這種情況是來源於“圖片分享”的功能需求,與普通圖片分享不同在於,該快照圖片是動態載入不顯示的。)
2.需求功能拆解
- 動態二維碼的實現
- 動態檢視生成快照的實現
3.踩坑點提要
- 獲取不到動態檢視的bitmap
- 無法獲取最新動態檢視的bitmap
4.開發實現
動態載入的檢視的佈局檔案程式碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/qrcodeContentLl" android:background="#F0E68C" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="100dp" android:text="二維碼快照" android:textSize="18sp" android:textStyle="italic" /> <ImageView android:id="@+id/qrcodeIv" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" android:layout_marginTop="@dimen/activity_vertical_margin" android:scaleType="fitCenter" /> <!--<TextView--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_marginTop="800dp"--> <!--android:text="ahahds"--> <!--android:layout_gravity="center"/>--> </LinearLayout>
大概樣式如下:
(上面的線框是用來顯示動態生成的二維碼圖片的)
a.動態二維碼的實現
關於這塊內容,網上有太多例子了,其實也不用詳解。主要是利用Zxing提供的jar包來進行處理。需要看這塊的詳細程式碼可以去文章最後提供的GitHub地址檢視,在此只提供下該jar包的資源下載(專案中若只涉及生成二維碼模組,那麼只要core核心jar包即可):點選下載>> core-3.3.0.jar
b.動態檢視生成快照的實現
private void inflateAndShowCaptureView() { if (hideView == null) { hideView = LayoutInflater.from(this).inflate(R.layout.layout_quick_capture, null); qrcodeIv = (ImageView) hideView.findViewById(R.id.qrcodeIv); hideView.setDrawingCacheEnabled(true);//設定控制元件允許繪製快取 hideView.measure(View.MeasureSpec.makeMeasureSpec(mainLayoutLl.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); hideView.layout(0, 0, hideView.getMeasuredWidth(), hideView.getMeasuredHeight()); } else { hideView.destroyDrawingCache();//要得到新的檢視,就得銷燬之前的快取 } showCaptureView(); } private void showCaptureView() { String content = contentEt.getText().toString().trim(); if (content == null || content.length() == 0) { return; } if (qrcodeIv.getWidth() == 0) { return; } Bitmap qrcodeBitmap = ZXingUtils.createQRImage(content, qrcodeIv.getWidth(), qrcodeIv.getHeight()); qrcodeIv.setImageBitmap(qrcodeBitmap);//先將生成的二維碼顯示在載入的檢視上 Bitmap bitmap = hideView.getDrawingCache(); // 獲取檢視的繪製快取(快照) if (bitmap != null) { showIv.setImageBitmap(bitmap); } }
1.首先獲取到檢視的bitmap是通過getDrawingCache()得到的。
- 若檢視是在介面上直接顯示出來的——>那麼使用該方法直接獲取bitmap是沒有問題的;
- 若檢視是動態載入且不顯示出來,那麼此時獲取bitmap是null。
此處的解決辦法就是手動給該檢視佈局:
有關於以上兩種方法的使用,可以參考這個文件的解釋:點選檢視>>hideView.measure(View.MeasureSpec.makeMeasureSpec(mainLayoutLl.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); hideView.layout(0, 0, hideView.getMeasuredWidth(), hideView.getMeasuredHeight());
當然,篇幅有點長,以下做點簡單解釋:
View.MeasureSpec.makeMeasureSpec(int size , int mode)中有兩個引數,size和mode,第一組MeasureSpec中我將size設定為了當前顯示頁面的佈局的寬度(也就是螢幕寬度),然後mode設定為EXACTLY——>所表示的意義是:給hideView中的子View指定了精確的寬度大小為當前螢幕的寬度。
mode有三種,EXACTLY,AT_MOST,UNSPECIFIED。在上面程式碼中,將高度的size指定為0,mode指定為 UNSPECIFIED 則表示——>整個動態載入的檢視高度指定為:依據於最後子View確認的高度。
若將第一組MeasureSpec的相關引數也改為size = 0, mode = UNSPECIFIED,則兩組圖對比顯示如下:
可以看到,動態生成的快照的寬度也變成了顯示二維碼的ImageView的寬度了。
擴充套件:如何在寬高均為size = 0 && mode= UNSPECIFIED 的情況下獲取整個螢幕大小的檢視呢?
——>用幾個隱藏的元件埋在檢視的四個邊界,啊哈哈哈哈哈!