Android WebView實(shí)現(xiàn)網(wǎng)頁(yè)滾動(dòng)截圖
WebView 網(wǎng)頁(yè)滾動(dòng)截屏,可對(duì)整個(gè)網(wǎng)頁(yè)進(jìn)行截屏而不是僅當(dāng)前屏幕哦!
注意若Web頁(yè)面存在position:fixed; 的話得在調(diào)用前設(shè)置為 position:absolute; 哦,否則會(huì)出現(xiàn)很多次的,請(qǐng)看下面的具體解說(shuō)吧?。?/p>
private static Bitmap getViewBitmapWithoutBottom(View v) {
if (null == v) {
return null;
}
v.setDrawingCacheEnabled(true);
v.buildDrawingCache();
if (Build.VERSION.SDK_INT >= 11) {
v.measure(View.MeasureSpec.makeMeasureSpec(v.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(v.getHeight(), View.MeasureSpec.EXACTLY));
v.layout((int) v.getX(), (int) v.getY(), (int) v.getX() + v.getMeasuredWidth(), (int) v.getY() + v.getMeasuredHeight());
} else {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
}
Bitmap bp = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight() - v.getPaddingBottom());
v.setDrawingCacheEnabled(false);
v.destroyDrawingCache();
return bp;
}
public static Bitmap getViewBitmap(View v) {
if (null == v) {
return null;
}
v.setDrawingCacheEnabled(true);
v.buildDrawingCache();
if (Build.VERSION.SDK_INT >= 11) {
v.measure(View.MeasureSpec.makeMeasureSpec(v.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(v.getHeight(), View.MeasureSpec.EXACTLY));
v.layout((int) v.getX(), (int) v.getY(), (int) v.getX() + v.getMeasuredWidth(), (int) v.getY() + v.getMeasuredHeight());
} else {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
}
Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.setDrawingCacheEnabled(false);
v.destroyDrawingCache();
return b;
}
/**
* 獲取 WebView 視圖截圖
* @param context
* @param view
* @return
*/
public static Bitmap getWebViewBitmap(Context context, WebView view) {
if (null == view) return null;
view.scrollTo(0, 0);
view.buildDrawingCache(true);
view.setDrawingCacheEnabled(true);
view.setVerticalScrollBarEnabled(false);
Bitmap b = getViewBitmapWithoutBottom(view);
// 可見高度
int vh = view.getHeight();
// 容器內(nèi)容實(shí)際高度
int th = (int)(view.getContentHeight()*view.getScale());
Bitmap temp = null;
if (th > vh) {
int w = getScreenWidth(context);
int absVh = vh - view.getPaddingTop() - view.getPaddingBottom();
do {
int restHeight = th - vh;
if (restHeight <= absVh) {
view.scrollBy(0, restHeight);
vh += restHeight;
temp = getViewBitmap(view);
} else {
view.scrollBy(0, absVh);
vh += absVh;
temp = getViewBitmapWithoutBottom(view);
}
b = mergeBitmap(vh, w, temp, 0, view.getScrollY(), b, 0, 0);
} while (vh < th);
}
// 回滾到頂部
view.scrollTo(0, 0);
view.setVerticalScrollBarEnabled(true);
view.setDrawingCacheEnabled(false);
view.destroyDrawingCache();
return b;
}
/**
* 拼接圖片
* @param newImageH
* @param newImageW
* @param background
* @param backX
* @param backY
* @param foreground
* @param foreX
* @param foreY
* @return
*/
private static Bitmap mergeBitmap(int newImageH, int newImageW, Bitmap background, float backX, float backY, Bitmap foreground, float foreX, float foreY) {
if (null == background || null == foreground) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(newImageW, newImageH, Bitmap.Config.RGB_565);
Canvas cv = new Canvas(bitmap);
cv.drawBitmap(background, backX, backY, null);
cv.drawBitmap(foreground, foreX, foreY, null);
cv.save(Canvas.ALL_SAVE_FLAG);
cv.restore();
return bitmap;
}
/**
* get the width of screen
*/
public static int getScreenWidth(Context ctx) {
int w = 0;
if (Build.VERSION.SDK_INT > 13) {
Point p = new Point();
((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(p);
w = p.x;
} else {
w = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
}
return w;
}
/**
* 保存圖片
* @param context
* @param bitmap
* @param file
* @param quality
* @return
*/
public static boolean save(Context context, Bitmap bitmap, File file, int quality) {
if (bitmap == null) return false;
// 獲得后綴格式
String abs = file.getAbsolutePath();
String suffix = abs.substring(abs.lastIndexOf(".")+1).toLowerCase();
Bitmap.CompressFormat format;
if ("jpg".equals(suffix) || "jpeg".equals(suffix)) {
format = Bitmap.CompressFormat.JPEG;
} else {
format = Bitmap.CompressFormat.PNG;
quality = 100;
}
if (file.exists() && ! file.delete()) return false;
try {
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(format, quality, stream);
stream.flush();
stream.close();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
return true;
} catch (Exception e) {
return false;
}
}
JS調(diào)用截屏操作
/**
* 屏幕截圖
* @param name
* @param isRecover
*/
@JavascriptInterface
public String Capture(String name, boolean isRecover) {
File dir = new File(Config.PUBLIC_PICTURES_PATH);
LogUtil.i("capture", dir.getAbsolutePath());
if (! dir.exists() && ! dir.mkdirs()) return null;
final File file = new File(dir, name);
String path = file.getAbsolutePath();
if (file.exists() && ! isRecover) return path;
body.post(new Runnable() {
@Override
public void run() {
Bitmap bitmap = CaptureUtil.getWebViewBitmap(activity, body);
if (null != bitmap) ImageUtil.save(activity, bitmap, file, 100);
}
});
return path;
}
@JavascriptInterface
public String Capture(String name) {
return Capture(name, true);
}
@JavascriptInterface
public String Capture() {
String name = String.valueOf(System.currentTimeMillis()) + ".png";
return Capture(name);
}
示例圖:我先通過(guò) JS 觸發(fā)顯示了一個(gè)原生的 Button按鈕, 然后WebView跳轉(zhuǎn)到 csdn 頁(yè)面,然后點(diǎn)擊截屏按鈕用來(lái)觸發(fā)網(wǎng)頁(yè)截屏的。下面的圖是我手動(dòng)截的圖,不是上面代碼的效果哈,下下面很長(zhǎng)的那張才是Java程序的網(wǎng)頁(yè)截圖。

測(cè)試CSDN的網(wǎng)頁(yè)完整截圖:比較長(zhǎng)哦~ 一般截圖的功能都用于特殊的頁(yè)面,如活動(dòng)頁(yè)面之類的,不會(huì)太長(zhǎng),那樣是沒(méi)有問(wèn)題的。若是這種滾動(dòng)到底部自動(dòng)加載的話可能就會(huì)很長(zhǎng)很長(zhǎng)很長(zhǎng)啦·····,自己看著辦吧。。

但這里有個(gè)BUG,頂部固定Banner條每次截屏都有,這個(gè)有解決辦法,不過(guò)得是你自己的網(wǎng)頁(yè)才有操作權(quán)限哦,需要修改JS啦。
當(dāng)截圖JS命令觸發(fā)前,把頂部懸浮的樣式設(shè)置為絕對(duì)定位,當(dāng)截屏完成后再改回固定定位即可,沒(méi)什么難度了。
截屏是需要一些時(shí)間的,所以需要預(yù)設(shè)一個(gè)定時(shí)器來(lái)操作,JS栗子如下:
JS.Capture 是 WebView 綁定的自定義 Javascript 類對(duì)象
var file = '';
var $header = $("#layout-header");
$header.css({ position: "absolute" });
setTimeout(function(){
if (typeof name == "function" || typeof name == "undefined") {
file = JS.Capture();
} else {
file = JS.Capture(name, isRecover);
}
}, 500);
setTimeout(function(){
JS.Toast("截圖已保存", "fast");
JS.Toast(file.replace("storage/emulated/0/", ""));
$header.css({ position: "fixed" });
if ($.isFunction(callback)) {
callback(file);
}
}, 1500);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android WebView打開網(wǎng)頁(yè)一片空白的解決方法
- Android開發(fā)筆記之如何正確獲取WebView的網(wǎng)頁(yè)Title
- 詳解android 用webview加載網(wǎng)頁(yè)(https和http)
- Android開發(fā)中使用WebView控件瀏覽網(wǎng)頁(yè)的方法詳解
- Android編程實(shí)現(xiàn)webview將網(wǎng)頁(yè)打包成apk的方法
- Android中替換WebView加載網(wǎng)頁(yè)失敗時(shí)的頁(yè)面
- Android中Webview打開網(wǎng)頁(yè)的同時(shí)發(fā)送HTTP頭信息方法
- Android webView如何輸出自定義網(wǎng)頁(yè)
相關(guān)文章
Android 圖片特效如何實(shí)現(xiàn)及總結(jié)
這篇文章主要介紹了Android 圖形特效如何實(shí)現(xiàn)及總結(jié)的相關(guān)資料,這里對(duì)Android圖像特效的實(shí)現(xiàn)比如:旋轉(zhuǎn),放大,縮小,傾斜等,需要的朋友可以參考下2016-12-12
解析Android中string-array數(shù)據(jù)源的簡(jiǎn)單使用
本篇文章是對(duì)Android中string-array數(shù)據(jù)源的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android Activity切換(跳轉(zhuǎn))時(shí)出現(xiàn)黑屏的解決方法 分享
Android Activity切換(跳轉(zhuǎn))時(shí)出現(xiàn)黑屏的解決方法 分享,需要的朋友可以參考一下2013-06-06
Android如何使用RecyclerView打造首頁(yè)輪播圖
這篇文章主要為大家詳細(xì)介紹了Android如何使用RecyclerView打造首頁(yè)輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Android應(yīng)用中拍照后獲取照片路徑并上傳的實(shí)例分享
這篇文章主要介紹了Android應(yīng)用中拍照后獲取照片路徑并上傳的實(shí)例分享,文中使用MultipartEntityBuilder制作了一個(gè)簡(jiǎn)單的上傳工具,需要的朋友可以參考下2016-03-03
詳解Android應(yīng)用開發(fā)中Scroller類的屏幕滑動(dòng)功能運(yùn)用
這篇文章主要介紹了詳解Android應(yīng)用開發(fā)中Scroller類的屏幕滑動(dòng)功能運(yùn)用,文中包括各種觸摸滑屏手勢(shì)相關(guān)方法的示例,需要的朋友可以參考下2016-02-02
Android自定義View實(shí)現(xiàn)選座功能
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)選座功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
android圖像繪制(六)獲取本地圖片或拍照?qǐng)D片等圖片資源
從SD卡中獲取圖片資源,或者拍一張新的圖片,然后再進(jìn)行處理(直接處理返回圖片/獲得圖片的地址再處理)接下來(lái)為您詳細(xì)介紹,感興趣的朋友可以了解下2013-01-01

