这是一个基础的自定义view,供大家参考
先看效果:
要实现手写签名,我们的关键是实现一个自定义view,可以绘制出轨迹,这里,我起名为SignView,并使之继承View,并继承接口View.OnTouchListener,并建立一些变量
public class SignView extends View implements View.OnTouchListener{
Bitmap bitmap=null;
Path path;
Rect boundary;
Canvas canvas1;
boolean isdraw;//用于判断路径是否为空
public int bound,stroke;//用来提供给Activity设置使用
private int width,height;
}
实现自定义view,至少要重写ondraw和构造方法,这里我们把4个构造方法全部写出来,并在其中加一些初始化的操作
public SignView(Context context) {
super(context);
init();
}
public SignView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public SignView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public SignView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
在init中,我们要初始化我们的绘制轨迹,画笔的粗细,还有set接口,可能还会用到边界,我们都把他们初始化一下
private void init() {
path=new Path();
isdraw=false;
stroke=8;
bound=8;
setOnTouchListener(this);
}
我们这里不需要重写onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
我们重写一下onLayout,用来设置边界和bitmap的大小,注意:onLayout中一定可以获取到getWidth()和getHeight()
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
width=getWidth();
height=getHeight();
bitmap = Bitmap.createBitmap(width-bound, height-bound, Bitmap.Config.ARGB_8888);
canvas1=new Canvas(bitmap);
boundary=new Rect(bound,bound,width-bound,height-bound);
}
接着我们运行onDraw,代码很简单,就是把之前的path和边框画出来
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
paint.setStrokeWidth(stroke);
canvas.drawPath(path,paint);
canvas1.drawPath(path,paint);
canvas.drawRect(boundary,paint);
}
我们继承了View.OnTouchListener,自然需要重写onTouch
@Override
public boolean onTouch(View v, MotionEvent event) {
isdraw=true;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN://当手指按下的时候触发
path.moveTo(event.getX(),event.getY());
invalidate();
break;
case MotionEvent.ACTION_MOVE://当手指移动的时候触发
path.lineTo(event.getX(),event.getY());
invalidate();
break;
}
return true;
}
剩下的就是动态设置边框和画笔粗细了,这部分可有可无,主要是方便别人调用我们的自定义view
public float getBound() {
return bound;
}
public void setBound(int bound) {
this.bound = bound;
}
public void setStroke(int stroke) {
this.stroke = stroke;
}
public float getStroke() {
return stroke;
}
我们还需要返回bitmap
public Bitmap getBitmap(){
if(!isdraw)
return null;
return bitmap;
}
还需要清空画布
public void clear(){
path.reset();
bitmap = Bitmap.createBitmap(width-bound, height-bound, Bitmap.Config.ARGB_8888);
canvas1=new Canvas(bitmap);
invalidate();
}
如此一来,我们的自定义view就完美了。
接着我们来看如何使用它
首先,在xml中创建他
接着,在Activity中绑定他
SignView signView=findViewById(R.id.signview);
当我们需要他返回bitmap的时候,只需运行
signView.getBitmap()
当我们需要清空画布的时候,只需运行
signView.clear();
是不是很简单呢?
快去实现吧!
将bitmap保存到本地
完整代码下载