Android自定義view-電子簽名畫板

   電子簽名作爲用戶的電子憑證,在很多業務中都有用到!

一.自定義電子簽名畫板

package com.kxf.androidtestdemo.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

/**
 * @ProjectName: AndroidTestDemo
 * @Package: com.kxf.androidtestdemo.view
 * @ClassName: ElecSignatureView
 * @Description: 電子簽名畫板
 * @Author: kuangxuefeng
 * @qq: 1024883177
 * @CreateDate: 2020/4/15 16:29
 */
public class ElecSignatureView extends View {
    private int widthSize;//畫板的寬
    private int heightSize;
    private Bitmap bitmap;//整個畫板顯示的位圖
    private Paint paint = new Paint();//畫板的畫筆
    private Canvas canvas = new Canvas();//畫板的畫布
    private float xTouch = 0;//移動的位置
    private float yTouch = 0;

    public ElecSignatureView(Context context) {
        super(context);
        initData();
    }

    public ElecSignatureView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initData();
    }

    public ElecSignatureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ElecSignatureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initData();
    }

    private void initData() {
        setClickable(true);//設置爲可點擊才能獲取到MotionEvent.ACTION_MOVE
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(7);
        //設置是否使用抗鋸齒功能,抗鋸齒功能會消耗較大資源,繪製圖形的速度會減慢
        paint.setAntiAlias(true);
        //設置是否使用圖像抖動處理,會使圖像顏色更加平滑飽滿,更加清晰
        paint.setDither(true);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.d("ElecSignatureView", "onMeasure widthMeasureSpec=" + widthMeasureSpec + "  heightMeasureSpec=" + heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        Log.d("ElecSignatureView", "onMeasure widthSize=" + widthSize + "  heightSize=" + heightSize);
        initBitmap();
    }

    private void initBitmap(){
        if (null != bitmap){
            bitmap.recycle();
        }
        bitmap = Bitmap.createBitmap(widthSize, heightSize, Bitmap.Config.ARGB_8888);
        Paint paint = new Paint();
        paint.setColor(Color.rgb(220, 220, 220));
        canvas.setBitmap(bitmap);
        canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.d("ElecSignatureView", "onDraw");
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, 0, 0, paint);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("ElecSignatureView", "onTouchEvent event=" + event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                xTouch = event.getX();
                yTouch = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                canvas.drawLine(xTouch, yTouch, event.getX(), event.getY(), paint);
                xTouch = event.getX();
                yTouch = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 獲取畫好的電子簽名
     * @return
     */
    public Bitmap getBitmap() {
        return bitmap;
    }

    /**
     * 清除電子簽名
     */
    public void clear(){
        initBitmap();
        invalidate();
    }
}

自定義view的詳細流程就不具體介紹了!

       initData主要是完成畫筆的初始化;onMeasure是爲了獲取當前組件的大小,以便於初始化一塊大小一致的畫布;onDraw的時候將畫好的位圖繪製在view要顯示的畫布上。onTouchEvent獲取用戶劃過的路徑,繪製在位圖上。

二.佈局中使用

<?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=".activity.ElecSignatureActivity">

    <com.kxf.androidtestdemo.view.ElecSignatureView
        android:id="@+id/elec"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:text="save"
            android:onClick="onSave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:text="Clear"
            android:onClick="onClear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

三.activity獲取畫好的數據

package com.kxf.androidtestdemo.activity;

import androidx.appcompat.app.AppCompatActivity;

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

import com.kxf.androidtestdemo.R;
import com.kxf.androidtestdemo.view.ElecSignatureView;

public class ElecSignatureActivity extends AppCompatActivity {

    private ElecSignatureView elec;
    private ImageView iv;

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

        elec = findViewById(R.id.elec);
        iv = findViewById(R.id.iv);
    }

    public void onSave(View view) {
        Bitmap bm = elec.getBitmap();

        iv.setImageBitmap(bm);
    }

    public void onClear(View view) {
        elec.clear();
    }
}

四.效果如下

 

五.項目源碼

https://kuangxuefeng.coding.net/p/AndroidTestDemo/d/AndroidTestDemo/git

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章