下面我们来写一个自定义可以触控屏幕绘制线条的View;
package com.signaturedemo.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class SignatureView extends View {
private Paint mPaint = new Paint();
private Path mPath = new Path();
public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public SignatureView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
private void init() {
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(5f);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawPath(mPath, mPaint);
}
private float cur_x, cur_y;
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
cur_x = eventX;
cur_y = eventY;
mPath.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
myDraw(event); //减锯齿描绘
mPath.quadTo(cur_x, cur_y, eventX, eventY);
cur_x = eventX;
cur_y = eventY;
break;
default:
return false;
}
invalidate();
return true;
}
/**
* 绘图时减锯齿操作
* @param event
*/
private void myDraw(MotionEvent event) {
int historySize = event.getHistorySize();
for(int i=0; i<historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
mPath.quadTo(cur_x, cur_y, historicalX, historicalY);
}
}
/**
* 清除描绘
*/
public void clear() {
mPath.reset();
invalidate();
}
}
上面就完成了一个自定义画板的View,然后在布xml文件中引用View即可;
<com.signaturedemo.view.SignatureView
android:id="@+id/view_signature"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
接下来可能我们就想要保存写好的个性签名图片,重点就来了!这就涉及到如何讲一个View视图生成一个图片对象(Bitmap)呢?一般有两种方法:
第一种
/**
* view_signature为我们要保存成图片的View
*/
view_signature.setDrawingCacheEnabled(true);
view_signature.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view_signature.layout(0, 0, view_signature.getMeasuredWidth(), view_signature.getMeasuredHeight());
view_signature.buildDrawingCache();
Bitmap bmp = view_signature.getDrawingCache();
这种方法我用了,不知是哪里的问题,得到的Bitmap对象为null,按照网上查找的方法就是这样写的。还是得到null,有知道的涉及到的望告知一下;
第二种, 这种就是我现在用的,可以很方便的把View视图转成Bitmap对象了。贴代码
Bitmap bmp = Bitmap.createBitmap(view_signature.getMeasuredWidth(), view_signature.getMeasuredHeight(), Config.ARGB_8888);
view_signature.draw(new Canvas(bmp));
大功告成了一半,那接下来就要存入本地咯。
/**
* 保存签名文件图片
* @param bmp Bitmap图片对象
* @param path 保存的路径
*/
public void creatBitmapFile(Bitmap bmp, String path) {
try {
File file = new File(mPath); //定义好mPath存的路径
if(!file.exists()) { //判断文件夹是否存在,不存在则创建
file.mkdir();
}
file = new File(path);
if(!file.exists()) {
file.createNewFile();
}
FileOutputStream fileOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fileOut);
fileOut.flush();
fileOut.close();
updatePhotos(file); //更新图库
Toast.makeText(this, R.string.msg_save_succ, Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("creatBitmapFile", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("creatBitmapFile", e.getMessage());
e.printStackTrace();
} finally {
}
}
/**
* 打开图库
*/
private void scanPicture() {
Intent it_gallery = new Intent();
it_gallery.addCategory(Intent.CATEGORY_OPENABLE);
it_gallery.setType("image/*");
startActivity(it_gallery);
}
/**
* 发送广播,图库更新照片
* @param file 新增的图片
*/
private void updatePhotos(File file) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
sendBroadcast(intent);
}
好了,成功保存签名的View视图文件。AndroidManifest.xml别忘了加上读写sd卡的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
大功终告成,附个效果截图吧