2021-10-28

Android 实现手写签名

  1. Activity
package com.example.saomaqiang.qianming;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.example.saomaqiang.R;

public class QianMingActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qian_ming);
        initView();
    }

    private void initView() {
        ImageView iv_sign = findViewById(R.id.iv_sign);
        FrameLayout frameLayout = findViewById(R.id.fl_view);
        SignatureView signatureView = new SignatureView(this);
        frameLayout.addView(signatureView);
        signatureView.requestFocus();


        Button btnClear = findViewById(R.id.btn_clear);
        btnClear.setOnClickListener((v) -> {
            signatureView.clear();
        });

        Button btnOk = findViewById(R.id.btn_ok);
        btnOk.setOnClickListener((v) -> {
            Bitmap imageBitmap = signatureView.getCachebBitmap();
            iv_sign.setImageBitmap(imageBitmap);
        });


    }
}

2.界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".qianming.QianMingActivity">

    <ImageView
        android:id="@+id/iv_sign"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_marginBottom="3dp"
        android:layout_weight="1"
        android:background="@color/white" />

    <FrameLayout
        android:id="@+id/fl_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/white" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/bottom_bar"
        android:paddingTop="3dp">

        <Button
            android:id="@+id/btn_ok"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="确定" />

        <Button
            android:id="@+id/btn_clear"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="清除" />
    </LinearLayout>
</LinearLayout>

3.自定义View

package com.example.saomaqiang.qianming;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;

public class SignatureView extends View {
    //画笔
    private Paint paint;

    //画布
    private Canvas cacheCanvas;

    //位图
    private Bitmap cachebBitmap;

    //图片保存路径
    private Path path;

    //位图缓存
    public Bitmap getCachebBitmap() {
        return cachebBitmap;
    }

    public SignatureView(Context context) {
        super(context);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        //设置画笔
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLACK);
        path = new Path();

        //创建位图
        cachebBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);

        //用自定义位图构建画布
        cacheCanvas = new Canvas(cachebBitmap);
        //设置画布为白色
        cacheCanvas.drawColor(Color.WHITE);
    }

    /**
     * 清除画板,重置画笔
     */
    public void clear() {
        if (cacheCanvas != null) {
            paint.setColor(Color.WHITE);
            cacheCanvas.drawPaint(paint);
            paint.setColor(Color.BLACK);
            cacheCanvas.drawColor(Color.WHITE);
            invalidate();
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(cachebBitmap, 0, 0, null);
        canvas.drawPath(path, paint);
    }

    @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        int curW = cachebBitmap != null ? cachebBitmap.getWidth() : 0;
        int curH = cachebBitmap != null ? cachebBitmap.getHeight() : 0;
        if (curW >= w && curH >= h) {
            return;
        }

        if (curW < w) curW = w;
        if (curH < h) curH = h;

        Bitmap newBitmap = Bitmap.createBitmap(curW, curH, Bitmap.Config.ARGB_8888);
        Canvas newCanvas = new Canvas();
        newCanvas.setBitmap(newBitmap);
        if (cachebBitmap != null) {
            newCanvas.drawBitmap(cachebBitmap, 0, 0, null);
        }
        cachebBitmap = newBitmap;
        cacheCanvas = newCanvas;
    }

    private float cur_x, cur_y;

    @Override public boolean onTouchEvent(MotionEvent event) {

        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                cur_x = x;
                cur_y = y;
                path.moveTo(cur_x, cur_y);
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                path.quadTo(cur_x, cur_y, x, y);
                cur_x = x;
                cur_y = y;
                break;
            }
            case MotionEvent.ACTION_UP: {
                cacheCanvas.drawPath(path, paint);
                path.reset();
                break;
            }
        }
        invalidate();
        return true;
    }
}


上一篇:Android技术分享| 【自习室】自定义View代替通知动画(2)


下一篇:windows平台pthread库应用