电子签名作为用户的电子凭证,在很多业务中都有用到!
一.自定义电子签名画板
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://gitee.com/kuangxuefeng/AndroidTestDemo