Created
December 5, 2017 14:50
-
-
Save eugeneek/6eb7733044f3f0055bc6d1ee063bcf72 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class SignatureView extends View { | |
| private Bitmap mBitmap; | |
| private Canvas mCanvas; | |
| private Path mPath; | |
| private Paint mBitmapPaint; | |
| private Paint mPaint; | |
| private Paint circlePaint; | |
| private Path circlePath; | |
| private int backgroundColor; | |
| private boolean isBlank; | |
| private float mX, mY; | |
| private static final float TOUCH_TOLERANCE = 4; | |
| public SignatureView(Context context) { | |
| super(context); | |
| init(context); | |
| } | |
| public SignatureView(Context context, @Nullable AttributeSet attrs) { | |
| super(context, attrs); | |
| init(context); | |
| } | |
| public SignatureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
| super(context, attrs, defStyleAttr); | |
| init(context); | |
| } | |
| private void init(Context context) { | |
| isBlank = true; | |
| mPath = new Path(); | |
| mBitmapPaint = new Paint(Paint.DITHER_FLAG); | |
| circlePaint = new Paint(); | |
| circlePath = new Path(); | |
| circlePaint.setAntiAlias(true); | |
| circlePaint.setColor(ContextCompat.getColor(context, R.color.colorAccent)); | |
| circlePaint.setStyle(Paint.Style.STROKE); | |
| circlePaint.setStrokeJoin(Paint.Join.MITER); | |
| circlePaint.setStrokeWidth( | |
| context.getResources().getDimensionPixelSize(R.dimen.signature_point_circle_stroke)); | |
| mPaint = new Paint(); | |
| mPaint.setAntiAlias(true); | |
| mPaint.setDither(true); | |
| mPaint.setColor(Color.BLACK); | |
| mPaint.setStyle(Paint.Style.STROKE); | |
| mPaint.setStrokeJoin(Paint.Join.ROUND); | |
| mPaint.setStrokeCap(Paint.Cap.ROUND); | |
| mPaint.setStrokeWidth( | |
| context.getResources().getDimensionPixelSize(R.dimen.signature_stroke)); | |
| backgroundColor = ContextCompat.getColor(context, R.color.colorWhite); | |
| setDrawingCacheEnabled(true); | |
| } | |
| public boolean isBlank() { | |
| return isBlank; | |
| } | |
| public void setBlank(boolean blank) { | |
| isBlank = blank; | |
| } | |
| public void clear() { | |
| isBlank = true; | |
| mCanvas.drawColor(backgroundColor); | |
| invalidate(); | |
| } | |
| public Bitmap getSignature() { | |
| return getDrawingCache(); | |
| } | |
| public void setBitmap(Bitmap bitmap) { | |
| mBitmap = bitmap; | |
| mCanvas = new Canvas(mBitmap); | |
| mCanvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); | |
| } | |
| @Override | |
| protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
| super.onSizeChanged(w, h, oldw, oldh); | |
| if (mBitmap == null) { | |
| mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); | |
| mCanvas = new Canvas(mBitmap); | |
| isBlank = true; | |
| } | |
| } | |
| @Override | |
| protected void onDraw(Canvas canvas) { | |
| super.onDraw(canvas); | |
| canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); | |
| canvas.drawPath(mPath, mPaint); | |
| canvas.drawPath(circlePath, circlePaint); | |
| } | |
| private void touch_start(float x, float y) { | |
| mPath.reset(); | |
| mPath.moveTo(x, y); | |
| mX = x; | |
| mY = y; | |
| } | |
| private void touch_move(float x, float y) { | |
| float dx = Math.abs(x - mX); | |
| float dy = Math.abs(y - mY); | |
| if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { | |
| mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); | |
| mX = x; | |
| mY = y; | |
| circlePath.reset(); | |
| circlePath.addCircle(mX, mY, 30, Path.Direction.CW); | |
| isBlank = false; | |
| } | |
| } | |
| private void touch_up() { | |
| mPath.lineTo(mX, mY); | |
| circlePath.reset(); | |
| // commit the path to our offscreen | |
| mCanvas.drawPath(mPath, mPaint); | |
| // kill this so we don't double draw | |
| mPath.reset(); | |
| } | |
| @Override | |
| public boolean onTouchEvent(MotionEvent event) { | |
| float x = event.getX(); | |
| float y = event.getY(); | |
| switch (event.getAction()) { | |
| case MotionEvent.ACTION_DOWN: | |
| touch_start(x, y); | |
| invalidate(); | |
| break; | |
| case MotionEvent.ACTION_MOVE: | |
| touch_move(x, y); | |
| invalidate(); | |
| break; | |
| case MotionEvent.ACTION_UP: | |
| touch_up(); | |
| invalidate(); | |
| break; | |
| } | |
| return true; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment