1.需求背景
需要實(shí)現(xiàn)一個(gè)動(dòng)態(tài)加載但不顯示出來的視圖,且該視圖上有個(gè)動(dòng)態(tài)生成的二維碼,后用其去生成一張快照(也就是圖片)。
(常見這種情況是來源于“圖片分享”的功能需求,與普通圖片分享不同在于,該快照?qǐng)D片是動(dòng)態(tài)加載不顯示的。)
2.需求功能拆解
-
動(dòng)態(tài)二維碼的實(shí)現(xiàn)
-
動(dòng)態(tài)視圖生成快照的實(shí)現(xiàn)
3.踩坑點(diǎn)提要
-
獲取不到動(dòng)態(tài)視圖的bitmap
-
無法獲取新動(dòng)態(tài)視圖的bitmap
4.開發(fā)實(shí)現(xiàn)
動(dòng)態(tài)加載的視圖的布局文件代碼:
-
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" />
-
-
-
-
-
-
-
-
LinearLayout>
大概樣式如下:
(上面的線框是用來顯示動(dòng)態(tài)生成的二維碼圖片的)
a.動(dòng)態(tài)二維碼的實(shí)現(xiàn)
關(guān)于這塊內(nèi)容,網(wǎng)上有太多例子了,其實(shí)也不用詳解。主要是利用Zxing提供的jar包來進(jìn)行處理。需要看這塊的詳細(xì)代碼可以去文章后提供的GitHub地址查看,在此只提供下該jar包的資源下載(項(xiàng)目中若只涉及生成二維碼模塊,那么只要core核心jar包即可):點(diǎn)擊下載>> core-3.3.0.jar
b.動(dòng)態(tài)視圖生成快照的實(shí)現(xiàn)
-
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是沒有問題的;
-
若視圖是動(dòng)態(tài)加載且不顯示出來,那么此時(shí)獲取bitmap是null。
此處的解決辦法就是手動(dòng)給該視圖布局:
-
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());
有關(guān)于以上兩種方法的使用,可以參考這個(gè)文檔的解釋:點(diǎn)擊查看>>
當(dāng)然,篇幅有點(diǎn)長,以下做點(diǎn)簡單解釋:
View.MeasureSpec.makeMeasureSpec(int size , int mode)中有兩個(gè)參數(shù),size和mode,組MeasureSpec中我將size設(shè)置為了當(dāng)前顯示頁面的布局的寬度(也就是屏幕寬度),然后mode設(shè)置為EXACTLY——>所表示的意義是:給hideView中的子View指定了精確的寬度大小為當(dāng)前屏幕的寬度。
mode有三種,EXACTLY,AT_MOST,UNSPECIFIED。在上面代碼中,將高度的size指定為0,mode指定為 UNSPECIFIED 則表示——>整個(gè)動(dòng)態(tài)加載的視圖高度指定為:依據(jù)于后子View確認(rèn)的高度。
若將組MeasureSpec的相關(guān)參數(shù)也改為size = 0, mode = UNSPECIFIED,則兩組圖對(duì)比顯示如下:
可以看到,動(dòng)態(tài)生成的快照的寬度也變成了顯示二維碼的ImageView的寬度了。
擴(kuò)展:如何在寬高均為size = 0 && mode= UNSPECIFIED 的情況下獲取整個(gè)屏幕大小的視圖呢?
——>用幾個(gè)隱藏的組件埋在視圖的四個(gè)邊界,啊哈哈哈哈哈!
2.通過destroyDrawingCache()來刪除之前的緩存。
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個(gè)人觀點(diǎn), 并不代表本站贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個(gè)個(gè)人學(xué)習(xí)交流的平臺(tái),網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對(duì)作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請(qǐng)及時(shí)聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對(duì)此聲明的最終解釋權(quán)。