2019-10-12

Hybrid App

中網(wǎng)頁部分的分享方式越來越趨向于多元化,比較常見的用戶操作方式有:復(fù)制網(wǎng)頁鏈接式,直接選擇目標(biāo)應(yīng)用自動(dòng)分享式等。其中,截圖行為,越來越成為豐富用戶操作、備受用戶喜愛的互動(dòng)方式之一,我們?cè)诤芏鄡?nèi)容社區(qū)類應(yīng)用中都能看到這種功能。這篇文章總結(jié)一下

Android 應(yīng)用中 WebView 截圖的實(shí)現(xiàn)方式。

WebView 作為一種特殊的控件,自然不能像其他系統(tǒng) View 或者截屏的方式來獲取截圖(多為截取長(zhǎng)圖)。如:

publicstaticBitmap getScreenShot(View view){

??View screenView = view.getRootView();

??screenView.setDrawingCacheEnabled(true);

??Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());

??screenView.setDrawingCacheEnabled(false);

??returnbitmap;

}

如果將上述代碼套在 WebView 上使用,將會(huì)得到內(nèi)容不完整的截圖。而事實(shí)上,WebView 系統(tǒng)本身提供有對(duì)應(yīng)的 API 來獲取 Bitmap 對(duì)象。

privateBitmap captureWebView(WebView webView){

?Picture picture = webView.capturePicture();

?intwidth = picture.getWidth();

?intheight = picture.getHeight();

?if(width > 0&& height > 0) {

??Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

??Canvas canvas = newCanvas(bitmap);

??picture.draw(canvas);

??returnbitmap;

?}

?returnnull;

}

獲取到 Bitmap 對(duì)象后,利用這段代碼可以將其保存到設(shè)備的存儲(chǔ)卡中

privatevoidsaveBitmap(Bitmap bitmap){

?File file = newFile(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");

?try{

??FileOutputStream fos = newFileOutputStream(file);

??bitmap.compress(CompressFormat.JPEG, 80, fos);

??fos.flush();

??fos.close();

?} catch(java.io.IOException e) {

??e.printStackTrace();

?}

}

簡(jiǎn)單兩步,大功告成。然而當(dāng)你在 Android 5.0 及更高版本系統(tǒng)的設(shè)備中操作時(shí),你會(huì)發(fā)現(xiàn),截圖顯示并不完全。雖然圖片寬高符合實(shí)際要求,但是內(nèi)容只包含當(dāng)前屏幕顯示區(qū)域內(nèi) WebView 的內(nèi)容。

原因在于,為了減少內(nèi)存占用和提升性能,從 Android 5.0 開始,系統(tǒng)能夠智能化地選擇部分 Html 文檔進(jìn)行渲染。所以,默認(rèn)情況下,我們只能截取到部分屏幕顯示區(qū)域內(nèi) WebView 的內(nèi)容,也就出現(xiàn)了上述問題。

不過,系統(tǒng)也提供了對(duì)應(yīng)的 API 來修改這一默認(rèn)優(yōu)化行為。代碼很簡(jiǎn)單:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

?WebView.enableSlowWholeDocumentDraw();

}

需要注意的是,這段代碼必須添加在 WebView 實(shí)例被創(chuàng)建之前。如果使用 Activity 的話,也就是在 setContentView() 方法前面。

雖然 capturePicture() 方法已經(jīng)能夠獲取 WebView 截圖,但是到 API 19 時(shí)該方法被系統(tǒng)廢棄掉了。取而代之的是使用 onDraw() 方法獲取獲取 Bitmap 對(duì)象。

privateBitmap captureWebView(WebView webView){

?floatscale = webView.getScale();

?intwidth = webView.getWidth();

?intheight = (int) (webView.getHeight() * scale);

?Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

?Canvas canvas = newCanvas(bitmap);

?webView.draw(canvas);

?returnbitmap;

}

這里又要提到的是, getScale() 方法從 API 17 開始也被系統(tǒng)廢棄掉了。所以獲取 scale 值的另一種更優(yōu)雅的方式是:

webView.setWebViewClient(newWebViewClient() {

?@Override

?publicvoidonScaleChanged(WebView view,floatoldScale, floatnewScale){

??super.onScaleChanged(view, oldScale, newScale);

??scale = newScale;

?}

});

最后一點(diǎn),在實(shí)際使用過程中,我們還需要考慮到 Bitmap 的內(nèi)存占用問題,做好異常捕獲,防止 OOM 的出現(xiàn)。

總結(jié)

以上所述是小編給大家介紹的Android 中WebView 截圖的實(shí)現(xiàn)方式,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家的支持!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容