最近在编写一个小项目的过程中需要将一个自定义的View绘制完成后的效果保存到本地的文件中。刚开始在网上看了很多代码,结果在我的项目中就是不行,非常纳闷。后来才发现,自己的自定义View中的onDraw()方法中由于逻辑问题,导致不是每次调用onDraw方法时都会进行绘制。所以,折腾了小半天,后来分析了一下原理,找到了问题所在,算是搞定了。现在将主要的保存代码记录下来,以后可能会用到哦。
因为要保存到本地成为图片,所以,需要申请相关的权限,这个很简单的。
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
其次就是保存View到图片的逻辑代码:
private void saveViewToPic(View view){
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final File file = new File(path, "create customer path" + ".png"); //指定我们要保存到那个文件中
try {
file.createNewFile();
Bitmap bitmap = createViewBitmap(view);
OutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
outputStream.close();
// 这里加入了MediaScanner为了能给让系统扫描到我们文件的变动
connectionClient = new MediaScannerConnection.MediaScannerConnectionClient() {
@Override
public void onMediaScannerConnected() {
connection.scanFile(file.getAbsolutePath(), null);
}
@Override
public void onScanCompleted(String path, Uri uri) {
connection.disconnect();
}
};
connection = new MediaScannerConnection(HeartInfoDetail.this, connectionClient);
connection.connect();
Toast.makeText(HeartInfoDetail.this, "图片保存在" + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
另一段代码就很简单了:
private Bitmap createViewBitmap(View view){
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
主要就是将我们需要保存的View绘制到bitmap中。
至此,我就可以实现对View保存到本地SD卡中了。通过这个要提醒自己的是,上面代码第4行中view.draw()其实就是调用了我们要保存的图片的绘制函数,将其绘制的数据绘制到了我们特定的canvas画布上,所以其工作原理和view的绘制原理是一样的,通过源码可以知道view.draw()函数中会调用到我们自定义View的时候重写的onDraw()函数,所以,要保证View能给正确的保存,要确保onDraw函数在每次draw函数调用时能正确执行。