電子簽名作爲用戶的電子憑證,在很多業務中都有用到!
一.自定義電子簽名畫板
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