项目里有时会有那些要签名啊,或者要手绘的要求,为此就会要求有这样的控件存在,这里介绍两个方法:
一、Android 自带的 GestureOverlayView,添加于API-4,主要是用于识别手势的。
对于签名也可以完成大部分工作,但是有个问题:多笔画的时候,两个笔画之间间隔太久会自动清空前面所有笔画。我还么有找解决方法。
使用很简单:
在你的xml文件里添加这个控件就可以(一个透明层):
- <android.gesture.GestureOverlayView
- android:id="@+id/gov"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#000000"
- android:gestureColor="#ffffff"
- android:fadeEnabled="false"
- android:gestureStrokeType="multiple"
- android:gestureStrokeLengthThreshold="0.1"
- android:gestureStrokeSquarenessThreshold="0.1"
- android:gestureStrokeAngleThreshold="0.1">
- </android.gesture.GestureOverlayView>
有几个属性简单解释一下:fadeEnable,是手势的淡出效果,在做签名的时候就不用了;gestureStrokeType,有两个值,single和multiple,单笔画和多笔画,签名用多笔画;
gestureStrokeLengthThreshold、gestureStrokeSquarenessThreshold、gestureStrokeAngleThreshold 分别是长度、方形、角度的最小识别值,简单说就是对手势的识别精细度。在签名的要求中可能不是很重要。
然后可以把这个签名(手势)保存成Bitmap:
- public Bitmap saveSignature() {
- GestureOverlayView gestureOverlayView = (GestureOverlayView)findViewById(R.id.gov);
- gestureOverlayView.setDrawingCacheEnabled(true);
- return Bitmap.createBitmap(gestureOverlayView.getDrawingCache());
- }
二、如果要求要可以多笔画间隔无限时,手动控制清空的情况,那么可以用自定义控件实现:
- public class DrawBoard extends View {
- private static final float STROKE_WIDTH = 5f; // 笔画的宽度
- /*
- * 笔画的一半宽度,用于在获取签名(手势)的矩形区域的时候将所有的笔画都框进去。
- * 因为左上角和右下角的点是在笔画的那个点的中心的,所以左上角(x,y)->(x-w/2, y-w/2), 右下角(x,y)->(x+w/2, y+w/2)
- */
- private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
- private Paint paint = new Paint();
- private Path path = new Path();
- private float lastTouchX;
- private float lastTouchY;
- private final RectF dirtyRect = new RectF(); // 用于框出签名(手势)的区域
- public DrawBoard(Context context, AttributeSet attrs) {
- super(context, attrs);
- paint.setAntiAlias(true); //反锯齿
- paint.setColor(Color.BLACK);
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeJoin(Paint.Join.ROUND); // 连接处圆润
- paint.setStrokeWidth(STROKE_WIDTH);
- }
- public void clear() {
- path.reset();
- invalidate();
- }
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawPath(path, paint);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- float eventX = event.getX();
- float eventY = event.getY();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- path.moveTo(eventX, eventY);
- lastTouchX = eventX;
- lastTouchY = eventY;
- return true;
- case MotionEvent.ACTION_MOVE:
- case MotionEvent.ACTION_UP:
- resetDirtyRect(eventX, eventY); // 和最后一个坐标值比较更新图形矩形左上角和右下角
- int historySize = event.getHistorySize();
- for (int i = 0; i < historySize; i++) {
- float historicalX = event.getHistoricalX(i);
- float historicalY = event.getHistoricalY(i);
- expandDirtyRect(historicalX, historicalY); // 和历史坐标值比较更新图形矩形左上角和右下角
- path.lineTo(historicalX, historicalY);
- }
- path.lineTo(eventX, eventY);
- break;
- default: return false;
- }
- invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
- (int) (dirtyRect.top - HALF_STROKE_WIDTH),
- (int) (dirtyRect.right + HALF_STROKE_WIDTH),
- (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); //刷新整个图型区域
- lastTouchX = eventX;
- lastTouchY = eventY;
- return true;
- }
- private void expandDirtyRect(float historicalX, float historicalY) {
- if (historicalX < dirtyRect.left) {
- dirtyRect.left = historicalX;
- } else if (historicalX > dirtyRect.right) {
- dirtyRect.right = historicalX;
- }
- if (historicalY < dirtyRect.top) {
- dirtyRect.top = historicalY;
- } else if (historicalY > dirtyRect.bottom) {
- dirtyRect.bottom = historicalY;
- }
- }
- private void resetDirtyRect(float eventX, float eventY) {
- dirtyRect.left = Math.min(lastTouchX, eventX);
- dirtyRect.right = Math.max(lastTouchX, eventX);
- dirtyRect.top = Math.min(lastTouchY, eventY);
- dirtyRect.bottom = Math.max(lastTouchY, eventY);
- }
- }
补充:
后面我找到了第一种方法笔画不自动消失的方法,主要是用setFadeOffset这个方法
可以参见项目:
http://download.csdn.net/detail/findsafety/8999255