您的位置:首页 > 移动开发 > Android开发

Android上自定义View实现电子签名功能

2016-06-14 17:48 861 查看
近来项目中遇到了实现电子签名的功能,现在已经完成,觉得可以,故把这一个模块抽取出来一个demo,供大家看看有什么可改进的。代码写的比较简单,代码就是注释,下面上效果图:



下面是代码
package com.hai.widget;

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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
* 可以签名的view
* Created by 黄海 on 2016/6/14.
*/
public class SignatureView extends View {
private static final String TAG = "SignatureView";
private Paint mPathPaint;
private Paint mBitmapPaint;
private Canvas mCanvas;
private Path mPath;
private Bitmap mBitmap;
/**
* 画图区域的最大位置
*/
private float mSmallX = 0, mSmallY = 0, mBigX = 0, mBigY = 0;
private float mPreX, mPreY;

public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

private void init() {
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPathPaint.setDither(true);
mPathPaint.setStyle(Paint.Style.STROKE);
mPathPaint.setStrokeWidth(10);
mPathPaint.setColor(Color.parseColor("#ff3f4a57"));
mPathPaint.setStrokeJoin(Paint.Join.ROUND);//线段结束处的形状
mPathPaint.setStrokeCap(Paint.Cap.ROUND);//线段开始结束处的形状
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
resetSign();
}

private void resetSign() {
mPath = new Path();
mBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(Color.TRANSPARENT);
mCanvas = new Canvas(mBitmap);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPathPaint);
}

/**
* 计算画图区域的位置
*
* @param x
* @param y
*/
private void computeDrawMaxRang(float x, float y) {
if (mSmallX == 0 && mSmallY == 0 && mBigX == 0 && mBigY == 0) {
mSmallX = mBigX = x;
mBigY = mSmallY = y;
} else {
mSmallX = Math.min(mSmallX, x);
mSmallY = Math.min(mSmallY, y);
mBigX = Math.max(mBigX, x);
mBigY = Math.max(mBigY, y);
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPreX = event.getX();
mPreY = event.getY();
computeDrawMaxRang(mPreX, mPreY);
mPath.reset();
mPath.moveTo(mPreX, mPreY);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
computeDrawMaxRang(x, y);
//绘制圆滑曲线(贝塞尔曲线)
mPath.quadTo(mPreX, mPreY, x, y);
mPreX = x;
mPreY = y;
break;
case MotionEvent.ACTION_UP:
computeDrawMaxRang(event.getX(), event.getY());
mPath.lineTo(event.getX(), event.getY());
mCanvas.drawPath(mPath, mPathPaint);
break;
}
invalidate();
return true;
}

/**
* 保存bitmap到文件
*
* @param fileapth
* @return 成功返回true,反之false
*/
public boolean SaveBitmapToFile(String fileapth) {
File file = new File(fileapth);
if (file.exists()) {
float signAreaWidth = mBigX - mSmallX;
float signAreaHeight = mBigY - mSmallY;
Bitmap bitmap = Bitmap.createBitmap(mBitmap, (int) mSmallX, (int) mSmallY, (int) signAreaWidth, (int) signAreaHeight, new Matrix(), true);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else
return false;
}

public void reset() {
resetSign();
invalidate();
}
}

Acitivty代码
package com.hai.activity;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupWindow;

import com.hai.R;
import com.hai.widget.SignatureView;

/**
* Created by 黄海 on 2016/5/24.
*/
public class MyTest extends Activity implements View.OnClickListener {
Button btn;
PopupWindow popupWindow;
SignatureView signatureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mytest);
btn = (Button) findViewById(R.id.btn);
}

public void clk(View v) {

popupWindow = new PopupWindow(this);
popupWindow.setContentView(View.inflate(this,R.layout.popupwindow,null));
popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
popupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
popupWindow.showAtLocation(btn, Gravity.CENTER,0,0);
View view=popupWindow.getContentView();
signatureView= (SignatureView) view.findViewById(R.id.signView);
view.findViewById(R.id.btn_cancel).setOnClickListener(this);
view.findViewById(R.id.btn_reset).setOnClickListener(this);
view.findViewById(R.id.btn_ok).setOnClickListener(this);

}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_cancel:
if (popupWindow!=null&&popupWindow.isShowing()){
popupWindow.dismiss();
}
break;

case R.id.btn_reset:
signatureView.reset();
break;
}
}
}


弹出窗口布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lay_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="vertical">

<com.hai.widget.SignatureView
android:id="@+id/signView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#AAF6EA7F" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">

<Button
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sure" />

<Button
android:id="@+id/btn_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="reset" />

<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="cancel" />
</LinearLayout>

</LinearLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android