本文主要介绍如何在界面上实现签名,并转换为bitmap。
自定义一个View
自定义一个view来实现界面画布的展示,以及对画笔的操作。
PathPointView:自定义的View
public class PathPointView extends View {
private float mX;
private float mY;
private Paint mGesturePaint = null;
private Path mPath = null;
public PathPointView(Context context, AttributeSet attrs) {
super(context, attrs);
mPath = new Path();//路径
mGesturePaint = new Paint();//创建画笔
mGesturePaint.setAntiAlias(true);
mGesturePaint.setStyle(Style.STROKE);//样式
mGesturePaint.setStrokeWidth(5);//宽度
mGesturePaint.setColor(Color.BLACK);//颜色
}
/**
* 这个View的点击事件
* @param event
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(event);
break;
case MotionEvent.ACTION_MOVE:
touchMove(event);
}
invalidate();// 更新绘制
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 通过画布绘制多点形成的图形
canvas.drawPath(mPath, mGesturePaint);
}
/**
* 手指点下屏幕时调用,获得手指点下的坐标
* @param event
*/
private void touchDown(MotionEvent event) {
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
mPath.moveTo(x, y);// mPath绘制的绘制起点
}
/**
* 手指在屏幕上滑动时调用
* @param event
*/
private void touchMove(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final float previousX = mX;
final float previousY = mY;
final float dx = Math.abs(x - previousX);
final float dy = Math.abs(y - previousY);
// 两点之间的距离大于等于3时,生成贝塞尔绘制曲线
if (dx >= 3 || dy >= 3) {
// 设置贝塞尔曲线的操作点为起点和终点的一半
float cX = (x + previousX) / 2;
float cY = (y + previousY) / 2;
// 二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点
mPath.quadTo(previousX, previousY, cX, cY);
// 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
mX = x;
mY = y;
}
}
/**
* 重置绘制路线,即隐藏之前绘制的轨迹
*/
public void reset() {
mPath.reset();
invalidate();// 更新绘制
}
}
Activity布局中将自定义的View添加进去
PathPointActivity:界面展示
- 将PathPointView自定义View,作为一个控件展示在PathPointActivity中。
public class PathPointActivity extends Activity implements OnClickListener {
PathPointView pointView;
Button btn_save;
Button btn_rest;
ImageView img;
Bitmap bitmap = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pathpoin);
initUI();
}
private void initUI() {
btn_save = (Button) findViewById(R.id.btn_save);
btn_save.setOnClickListener(this);
btn_rest = (Button) findViewById(R.id.btn_rest);
btn_rest.setOnClickListener(this);
pointView = (PathPointView) findViewById(R.id.pointView);
img = (ImageView) findViewById(R.id.img);
img.setVisibility(View.GONE);
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.btn_save:
img.setVisibility(View.VISIBLE);
bitmap = ImageData.getViewBitmap(pointView);// 将画布view显示生成图片
img.setImageBitmap(bitmap);
break;
case R.id.btn_rest:
img.setImageBitmap(null);
img.setVisibility(View.GONE);
pointView.reset();// 调用画布的清除方法
break;
default:
break;
}
}
}
activity_pathpoin布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
<Button
android:id="@+id/btn_rest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset" />
</LinearLayout>
<!-- 自定义的画布View -->
<com.example.a_test.PathPointView
android:id="@+id/pointView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ll"/>
<ImageView
android:id="@+id/img"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentRight="true"
android:background="@drawable/img_bg"
android:layout_alignParentTop="true" />
</RelativeLayout>
ImageData :工具类
- 将view布局转换为bitmap
public class ImageData {
/**
* 将view转换为bitmap
*
* @param v
* @return
*/
public static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
// Reset the drawing cache background color to fully transparent
// for the duration of this operation
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
// Restore the view
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(0);
return bitmap;
}
}
效果图:
点击保存按钮,再右上角不为生成图片进行展示签名。
点击清除按键,可重新进行签名。