初始情形
需要将图片、文字等信息进行组合拼接,生成一张新的图片保存。
即,保存View或Layout的快照。
特殊情况Webview特殊处理,见文末。
具体实现
主界面
模版一:gone状态
模版二:正常状态
模版三:WebView
.
第一种 Draw方式
- 测量出布局的的宽高
- 根据宽高使用Bitmap.createBitmap()方法创建
- 通过指定的bitmap创建画布对象
- 手动渲染整个布局(包含自布局)到画布对象
- 返回bitmap对象,包含这个布局的渲染
/**
* 从View获取Bitmap 使用Draw方式
*/
private Bitmap GetBitmapFromViewDraw(View view){
// 1.获取view宽高
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
// 2.创建bitmap
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// 3.创建画布对象
Canvas canvas = new Canvas(bitmap);
// 4.手动渲染View到指定的Canvas对象
view.draw(canvas);
// 5. 返回bitmap
return bitmap;
}
分别结果:
.
.
.
.
此方式特点
1. 但不能将设置为visibility=”gone”的View获取到。
2. 获取的快照大小等固定为模版展示的大小,可能会导致图片位置偏失。
3. 能够获取整个webView的快照
第二种 Cache方式
- 设置View开启缓存
- 创建缓存bitmap
- 获取并拷贝bitmap
- 关闭缓存
- 返回bitmap对象
/**
* 从View获得Bitmap 使用Cache方式
*/
private Bitmap GetBitmapFromViewCache(View view){
// 重新测量一次 适用于 visibility="gone"
if (View.GONE == view.getVisibility()) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
view.measure(widthSpec, heightSpec);
view.layout(0, 0, width, height);
}
// 1.缓存view
view.setDrawingCacheEnabled(true);
// 2.启用DrawingCache并创建位图
view.buildDrawingCache();
// 3.获取view缓存
Bitmap bitmap = view.getDrawingCache(true);
// 3.拷贝出来
bitmap = Bitmap.createBitmap(bitmap);
// 4.清除缓存
view.setDrawingCacheEnabled(false);
return bitmap;
}
.
此方式特点
1. 能将设置为visibility=”gone”的View获取到。
2. 获取的快照大小为xml设置中最大值,例如wrap会充满宽度。
3. 不能够获取webView可见范围外的内容。
.
分别结果:
.
.
.
.
推荐使用第一种方式
WebView不可见范围白屏问题
WebView针对5.0版本的应用程序有一个新的默认行为,减少了内存占用,提高性能通过明智地选择HTML文档的部分需要。但是这里我们需要使用onDraw()做自己的绘画同时访问的可视页面的方式以外的部分页面。
调用如下代码取消优化(调用在setContentView()之前):
// 取消 5.0 对WebView的优化
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebView.enableSlowWholeDocumentDraw();
}
同时还需要设置webView一个属性
<WebView
android:id="@+id/webview_template"
android:scrollbars="vertical"
android:layerType="software"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
白屏效果:
.
最后跟上保存bitmap到本地的方法
/**
* 将bitmap转成图片文件,并保存在文件夹中
*/
public static File saveBitmap(Context context, Bitmap bitmap, String name) throws Exception {
if (bitmap == null || context == null || TextUtils.isEmpty(name)) return null;
FileOutputStream fop;
File file = new File(Environment.getExternalStorageDirectory(), "测试图库");
if (!file.exists()) {
if (!file.mkdirs()) {
return null;
}
}
File image = new File(file, name + ".jpg");
fop = new FileOutputStream(image.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fop);
fop.close();
// // 其次把文件插入到系统图库 选择使用
// MediaStore.Images.Media.insertImage(context.getContentResolver(),
// image.getAbsolutePath(), name + ".jpg", null);
// // 最后通知图库更新
// context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
// Uri.parse("file:" + File.separator + File.separator + image.getPath())));
return image;
}
GitHub:图片快照截屏小demo;