Android 自定义View手写签名并保存图片
程序员文章站
2022-03-10 16:17:28
GIF压缩有问题,运行很顺滑!!! 1.自定义View——支持设置画笔颜色,画笔宽度,画板颜色,清除画板,检查是否有签名,保存画板图片(复制粘贴可直接使用) /** * Created by YyyyQ on 2020/3/5. * 电子签名 */ public class SignatureVie ......
gif压缩有问题,运行很顺滑!!!
1.自定义view——支持设置画笔颜色,画笔宽度,画板颜色,清除画板,检查是否有签名,保存画板图片(复制粘贴可直接使用)
/** * created by yyyyq on 2020/3/5. * 电子签名 */ public class signatureview extends view { private context context; //x轴起点 private float x; //y轴起点 private float y; //画笔 private final paint paint = new paint(); //路径 private final path path = new path(); //画布 private canvas canvas; //生成的图片 private bitmap bitmap; //画笔的宽度 private int paintwidth = 10; //签名颜色 private int paintcolor = color.black; //背景颜色 private int backgroundcolor = color.white; //是否已经签名 private boolean istouched = false; //签名开始与结束 public interface touch { void ontouch(boolean istouch); } private touch touch; public signatureview(context context) { super(context); init(context); } public signatureview(context context, @nullable attributeset attrs) { super(context, attrs); init(context); } public signatureview(context context, @nullable attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(context); } private void init(context context) { this.context = context; //抗锯齿 paint.setantialias(true); //样式 paint.setstyle(paint.style.stroke); //画笔颜色 paint.setcolor(paintcolor); //画笔宽度 paint.setstrokewidth(paintwidth); } @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); //创建于view大小一致的bitmap bitmap = bitmap.createbitmap(getwidth(), getheight(), bitmap.config.argb_8888); canvas = new canvas(bitmap); canvas.drawcolor(backgroundcolor); istouched = false; } @override public boolean ontouchevent(motionevent event) { if (touch != null) touch.ontouch(true); switch (event.getaction()) { //手指按下 case motionevent.action_down: touchdwon(event); break; //手指移动 case motionevent.action_move: istouched = true; if (touch != null) touch.ontouch(false); touchmove(event); break; //手指抬起 case motionevent.action_up: canvas.drawpath(path, paint); path.reset(); break; } // 更新绘制 invalidate(); return true; } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); //画此次笔画之前的签名 canvas.drawbitmap(bitmap, 0, 0, paint); // 通过画布绘制多点形成的图形 canvas.drawpath(path, paint); } //手指按下的方法 private void touchdwon(motionevent event) { //重置绘制路径 path.reset(); float downx = event.getx(); float downy = event.gety(); x = downx; y = downy; //绘制起点 path.moveto(downx, downy); } //手指滑动的方法 private void touchmove(motionevent event) { //当前的x,y坐标点 final float movex = event.getx(); final float movey = event.gety(); //之前的x,y坐标点 final float previousx = x; final float previousy = y; //获取绝对值 final float dx = math.abs(movex - previousx); final float dy = math.abs(movey - previousy); if (dx >= 3 || dy >= 3) { float cx = (movex + previousx) / 2; float cy = (movey + previousy) / 2; path.quadto(previousx, previousy, cx, cy); x = movex; y = movey; } } /** * 设置画笔颜色 * * @param paintcolor */ public void setpaintcolor(int paintcolor) { this.paintcolor = paintcolor; paint.setcolor(paintcolor); } /** * 设置画笔宽度 * * @param paintwidth */ public void setpaintwidth(int paintwidth) { this.paintwidth = paintwidth; paint.setstrokewidth(paintwidth); } /** * 设置画板颜色 * * @param canvascolor */ public void setcanvascolor(int canvascolor) { this.backgroundcolor = canvascolor; } /** * 清除画板 */ public void clear() { if (canvas != null) { istouched = false; //更新画板 paint.setcolor(paintcolor); paint.setstrokewidth(paintwidth); canvas.drawcolor(backgroundcolor, porterduff.mode.clear); invalidate(); } } /** * 获取画板的bitmap * * @return */ public bitmap getbitmap() { setdrawingcacheenabled(true); builddrawingcache(); bitmap bitmap = getdrawingcache(); setdrawingcacheenabled(false); return bitmap; } /** * 是否有签名 * * @return */ public boolean getsigstatus() { return istouched; } /** * 保存画板 * * @param path 保存到路径 */ @suppresslint("wrongthread") public boolean save(string path) throws ioexception { bitmap bitmap = this.bitmap; bytearrayoutputstream bos = new bytearrayoutputstream(); bitmap.compress(bitmap.compressformat.png, 100, bos); byte[] buffer = bos.tobytearray(); if (buffer != null) { file file = new file(path); if (file.exists()) { file.delete(); } outputstream outputstream = new fileoutputstream(file); outputstream.write(buffer); outputstream.close(); return true; } else { return false; } } }
2.xml布局引用自定义view(注意包名)
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--自定义view的绝对路径--> <com.example.customviewdemo.view.signatureview android:id="@+id/signature" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#fff" /> <linearlayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_margin="20dp" android:orientation="horizontal"> <button android:id="@+id/clear" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="清除" /> <button android:id="@+id/issignature" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginleft="10dp" android:layout_weight="1" android:gravity="center" android:text="是否签名" /> <button android:id="@+id/save" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginleft="10dp" android:layout_weight="1" android:gravity="center" android:text="保存" /> </linearlayout> </linearlayout>
3.activity调用
/**
* created by yyyyq on 2020/3/9.
*/
public class signatureactivity extends appcompatactivity {
@override
protected void oncreate(@nullable bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_signature);
signatureview signatureview = findviewbyid(r.id.signature);
//设置画笔颜色(可以不设置--默认画笔宽度10,画笔颜色黑,背景颜色白)
signatureview.setpaintcolor(color.black);
signatureview.setpaintwidth(20);
signatureview.setcanvascolor(color.white);
//清除
button clear = findviewbyid(r.id.clear);
clear.setonclicklistener(view -> {
signatureview.clear();
//设置画笔颜色(可以不设置--默认画笔宽度10,画笔颜色黑,背景颜色白)
signatureview.setpaintcolor(color.black);
signatureview.setpaintwidth(20);
signatureview.setcanvascolor(color.white);
});
//是否含有签名
button issignature = findviewbyid(r.id.issignature);
issignature.setonclicklistener(view -> {
if (signatureview.getsigstatus()) {
toast.maketext(signatureactivity.this, "有签名", toast.length_short).show();
} else {
toast.maketext(signatureactivity.this, "无签名", toast.length_short).show();
}
});
//保存
button save = findviewbyid(r.id.save);
save.setonclicklistener(view -> {
try {
if (signatureview.save("/sdcard/yyyyq.png")) {
toast.maketext(signatureactivity.this, "保存成功", toast.length_short).show();
} else {
toast.maketext(signatureactivity.this, "保存失败", toast.length_short).show();
}
} catch (ioexception e) {
e.printstacktrace();
}
});
}
}
上一篇: JS--排序算法之简单排序
下一篇: 路由配置IP与静态路由