一、概述
app中有需求需要将View转化为图片并保存到本地,这里分两种情况:
1.View本身已经显示在界面上
2.View还没有添加到界面上或者没有显示(绘制)过
二、实现方法
对于上述的第一种情况我使用下面代码即可:
private void viewSaveToImage(View view) { view.setDrawingCacheEnabled(true); view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); view.setDrawingCacheBackgroundColor(Color.WHITE); // 把一个View转换成图片 Bitmap cachebmp = loadBitmapFromView(view); FileOutputStream fos; String imagePath = ""; try { // 判断手机设备是否有SD卡 boolean isHasSDCard = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); if (isHasSDCard) { // SD卡根目录 File sdRoot = Environment.getExternalStorageDirectory(); File file = new File(sdRoot, Calendar.getInstance().getTimeInMillis()+".png"); fos = new FileOutputStream(file); imagePath = file.getAbsolutePath(); } else throw new Exception("创建文件失败!"); cachebmp.compress(Bitmap.CompressFormat.PNG, 90, fos); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } LogUtil.e("imagePath="+imagePath); view.destroyDrawingCache(); } private Bitmap loadBitmapFromView(View v) { int w = v.getWidth(); int h = v.getHeight(); Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bmp); c.drawColor(Color.WHITE); /** 如果不设置canvas画布为白色,则生成透明 */ v.layout(0, 0, w, h); v.draw(c); return bmp; }
如果是第二种,还这样使用的话,就会报错了,因为View在添加到容器中之前并没有得到实际的大小,所以首先需要指定View的大小:
DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 屏幕宽度(像素) int height = metric.heightPixels; // 屏幕高度(像素) View mingpianView = LayoutInflater.from(this).inflate(R.layout.view_team_mingpian, null, false); layoutView(mingpianView, width, height);
//然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了: private void layoutView(View v, int width, int height) { // 整个View的大小 参数是左上角 和右下角的坐标 v.layout(0, 0, width, height); int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); int measuredHeight = View.MeasureSpec.makeMeasureSpec(10000, View.MeasureSpec.AT_MOST); /** 当然,measure完后,并不会实际改变View的尺寸,需要调用View.layout方法去进行布局。 * 按示例调用layout函数后,View的大小将会变成你想要设置成的大小。 */ v.measure(measuredWidth, measuredHeight); v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); }
然后再调用viewSaveToImage(mingpianView);方法即可。