欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 自定义View手写签名并保存图片

程序员文章站 2022-06-19 10:27:51
GIF压缩有问题,运行很顺滑!!! 1.自定义View——支持设置画笔颜色,画笔宽度,画板颜色,清除画板,检查是否有签名,保存画板图片(复制粘贴可直接使用) /** * Created by YyyyQ on 2020/3/5. * 电子签名 */ public class SignatureVie ......

Android 自定义View手写签名并保存图片

    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();
}

});

}
}