Android: digital signature using Bezier

enter image description here
I am trying to make two draws digitally using Bezier as shown above in the image. When I touch and try to draw a line, then the result is a dotted line, but does not become continuous. A simple signature made using a simple signature but I want to create a smoother curve using Bezier with touch pressure. tried this link

SignatureViewDemo.java

public class SignatureViewDemo extends View { private int color = Color.BLACK; private Bitmap m_Bitmap; private final Paint m_BorderPaint; private Canvas m_Canvas; private Point m_CropBotRight; private Point m_CropTopLeft; private float m_CurrentX; private float m_CurrentY; private final float m_DesiredDash; private float m_LastWidth = 6.5F; private Paint m_PenPaint; private int m_PointIndex = 0; private ArrayList<Point> m_Points = new ArrayList<Point>(); private final float m_StrokeWidth; boolean m_Empty; public SignatureViewDemo(Context paramContext) { this(paramContext, null); } public SignatureViewDemo(Context paramContext, AttributeSet paramAttributeSet) { this(paramContext, paramAttributeSet, 0); } public SignatureViewDemo(Context paramContext, AttributeSet paramAttributeSet, int paramInt) { super(paramContext, paramAttributeSet, paramInt); setFocusable(true); this.m_PenPaint = new Paint(); this.m_PenPaint.setAntiAlias(true); this.m_PenPaint.setColor(Color.BLACK); this.m_PenPaint.setStrokeWidth(5.0F); this.m_PenPaint.setStrokeJoin(Paint.Join.ROUND); this.m_PenPaint.setStrokeCap(Paint.Cap.ROUND); this.m_CurrentY = (0.0F / 0.0F); this.m_CurrentX = (0.0F / 0.0F); this.m_StrokeWidth = 5.0F; this.m_DesiredDash = 10.0F; this.m_BorderPaint = new Paint(); this.m_BorderPaint.setColor(Color.BLACK); this.m_BorderPaint.setStyle(Paint.Style.STROKE); this.m_BorderPaint.setStrokeWidth(this.m_StrokeWidth); } public void addBezier(Bezier paramBezier, float paramFloat1, float paramFloat2) { if (this.m_Bitmap == null) { this.m_Bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); this.m_Canvas = new Canvas(this.m_Bitmap); } paramBezier.draw(this.m_Canvas, this.m_PenPaint, paramFloat1, paramFloat2); } public void addPoint(Point paramPoint) { if ((paramPoint.getX() < this.m_CropTopLeft.getX()) && (paramPoint.getX() >= 0.0F)) this.m_CropTopLeft.setX(paramPoint.getX()); if ((paramPoint.getY() < this.m_CropTopLeft.getY()) && (paramPoint.getY() >= 0.0F)) this.m_CropTopLeft.setY(paramPoint.getY()); if ((paramPoint.getX() > this.m_CropBotRight.getX()) && (paramPoint.getX() <= this.m_Canvas.getWidth())) this.m_CropBotRight.setX(paramPoint.getX()); if ((paramPoint.getY() > this.m_CropBotRight.getY()) && (paramPoint.getY() <= this.m_Canvas.getHeight())) this.m_CropBotRight.setY(paramPoint.getY()); this.m_Points.add(paramPoint); drawPoints(); } // public void clear() { // if (this.m_Canvas == null) // this.m_Canvas.drawColor(0, PorterDuff.Mode.CLEAR); // invalidate(); // // return; // } public void clear() { if (this.m_Canvas == null) return; while (m_Empty) { m_Canvas.drawColor(0, PorterDuff.Mode.CLEAR); m_Empty = true; invalidate(); return; } } public void drawBitmap(Bitmap paramBitmap) { clear(); if ((paramBitmap != null) && (this.m_Canvas != null) && (this.m_Canvas.getWidth() != 0) && (this.m_Canvas.getHeight() != 0)) { Matrix localMatrix = new Matrix(); localMatrix.setRectToRect( new RectF(0.0F, 0.0F, paramBitmap.getWidth(), paramBitmap .getHeight()), new RectF(0.0F, 0.0F, this.m_Canvas.getWidth(), this.m_Canvas.getHeight()), Matrix.ScaleToFit.CENTER); this.m_Canvas.drawBitmap(paramBitmap, localMatrix, null); m_Empty = false; } invalidate(); } public void drawPoints() { if ((m_Points.size() >= 4) && (4 + this.m_PointIndex <= this.m_Points.size())) { Point localPoint1 = (Point) this.m_Points.get(this.m_PointIndex); Point localPoint2 = (Point) this.m_Points .get(1 + this.m_PointIndex); Point localPoint3 = (Point) this.m_Points .get(2 + this.m_PointIndex); Point localPoint4 = (Point) this.m_Points .get(3 + this.m_PointIndex); Bezier localBezier = new Bezier(localPoint1, localPoint2, localPoint3, localPoint4); localBezier.setColor(Color.GREEN); float f = strokeWidth(8.0F / localPoint4.velocityFrom(localPoint1)); addBezier(localBezier, this.m_LastWidth, f); invalidate(); this.m_LastWidth = f; this.m_PointIndex = (3 + this.m_PointIndex); m_Empty = false; } } public boolean isEmpty() { return m_Empty; } public Bitmap getBitmap() { return this.m_Bitmap; } public int getColor() { return this.color; } protected void onDraw(Canvas paramCanvas) { if (this.m_Bitmap != null) paramCanvas.drawBitmap(this.m_Bitmap, 0.0F, 0.0F, null); } protected void onMeasure(int paramInt1, int paramInt2) { int i = View.MeasureSpec.getSize(paramInt1); int j = View.MeasureSpec.getSize(paramInt2); this.m_CropTopLeft = new Point(i, j); this.m_CropBotRight = new Point(0.0F, 0.0F); setMeasuredDimension(i, j); } protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) { Bitmap localBitmap = Bitmap.createBitmap(paramInt1, paramInt2, Bitmap.Config.ARGB_8888); this.m_Canvas = new Canvas(localBitmap); float f1 = 2.0F * (this.m_Canvas.getWidth() + this.m_Canvas.getHeight() - 2.0F * this.m_StrokeWidth); float f2 = f1 * this.m_DesiredDash / (Math.round(f1 / (4.0F * this.m_DesiredDash)) * (4.0F * this.m_DesiredDash)); Paint localPaint = this.m_BorderPaint; float[] arrayOfFloat = new float[2]; arrayOfFloat[0] = f2; arrayOfFloat[1] = f2; localPaint.setPathEffect(new DashPathEffect(arrayOfFloat, f2 / 2.0F)); clear(); if (this.m_Bitmap != null) { Rect localRect = new Rect(0, 0, this.m_Canvas.getWidth(), this.m_Canvas.getHeight()); this.m_Canvas.drawBitmap(this.m_Bitmap, null, localRect, null); m_Empty = false; } this.m_Bitmap = localBitmap; } public boolean onTouchEvent(MotionEvent paramMotionEvent) { int i = 0xFF & paramMotionEvent.getAction(); if (i == 0) { this.m_CurrentX = paramMotionEvent.getX(); this.m_CurrentY = paramMotionEvent.getY(); addPoint(new Point(this.m_CurrentX, this.m_CurrentY, paramMotionEvent.getEventTime())); getParent().requestDisallowInterceptTouchEvent(true); } // while (m_Empty) { if ((i == 1) || (i == 3)) { this.m_CurrentY = (0.0F / 0.0F); this.m_CurrentX = (0.0F / 0.0F); this.m_Points.clear(); this.m_PointIndex = 0; getParent().requestDisallowInterceptTouchEvent(false); } // if ((this.m_Points.size() < 4) || (4 + this.m_PointIndex > // this.m_Points.size())) // while (1 + this.m_PointIndex <= this.m_Points.size()) drawPoints(); if ((i == 2) || (i == 1)) { for (int j = 0; j < paramMotionEvent.getHistorySize(); j++) addPoint(new Point(paramMotionEvent.getHistoricalX(j), paramMotionEvent.getHistoricalY(j), paramMotionEvent.getHistoricalEventTime(j))); addPoint(new Point(paramMotionEvent.getX(), paramMotionEvent.getY(), paramMotionEvent.getEventTime())); } // } return true; } public void setColor(int paramInt) { this.color = Color.BLACK; } public Point getCropBotRight() { return this.m_CropBotRight; } public Point getCropTopLeft() { return this.m_CropTopLeft; } // public float strokeWidth(float paramFloat) { // if (paramFloat > 11.0F) // paramFloat = 10.0F; // if (paramFloat < 5.0F) // paramFloat = 6.0F; // return paramFloat; // } public float strokeWidth(float paramFloat) { if (paramFloat > 11.0F) paramFloat = 10.0F; while (m_Empty) { if (paramFloat < 5.0F) paramFloat = 6.0F; return paramFloat; } return paramFloat; } } 

Point.java

  private long time; private float x; private float y; public Point(float paramFloat1, float paramFloat2) { this.x = paramFloat1; this.y = paramFloat2; } public Point(float paramFloat1, float paramFloat2, long paramLong) { this.x = paramFloat1; this.y = paramFloat2; this.time = paramLong; } protected float distanceTo(Point paramPoint) { float f1 = this.x - paramPoint.getX(); float f2 = this.y - paramPoint.getY(); return FloatMath.sqrt(f1 * f1 + f2 * f2); } public long getTime() { return this.time; } public float getX() { return this.x; } public float getY() { return this.y; } public void setX(float paramFloat) { this.x = paramFloat; } public void setY(float paramFloat) { this.y = paramFloat; } public float velocityFrom(Point paramPoint) { return distanceTo(paramPoint) / (this.time - paramPoint.time); } } 

Bezier.java

 public class Bezier { private Point controlPointOne; private Point controlPointTwo; private int drawSteps; private Point endPoint; private int mColor; private Point startPoint; public Bezier() { } public Bezier(Point paramPoint1, Point paramPoint2, Point paramPoint3, Point paramPoint4) { this.startPoint = paramPoint1; this.controlPointOne = paramPoint2; this.controlPointTwo = paramPoint3; this.endPoint = paramPoint4; this.drawSteps = ((int) (paramPoint1.distanceTo(paramPoint2) + paramPoint2.distanceTo(paramPoint3) + paramPoint3 .distanceTo(paramPoint4))); } public void draw(Canvas paramCanvas, Paint paramPaint, float paramFloat1, float paramFloat2) { float f1 = paramFloat2 - paramFloat1; for (int i = 0; i < this.drawSteps; i++) { float f2 = i / this.drawSteps; float f3 = f2 * f2; float f4 = f3 * f2; float f5 = 1.0F - f2; float f6 = f5 * f5; float f7 = f6 * f5; float f8 = f7 * this.startPoint.getX() + f2 * (3.0F * f6) * this.controlPointOne.getX() + f3 * (3.0F * f5) * this.controlPointTwo.getX() + f4 * this.endPoint.getX(); float f9 = f7 * this.startPoint.getY() + f2 * (3.0F * f6) * this.controlPointOne.getY() + f3 * (3.0F * f5) * this.controlPointTwo.getY() + f4 * this.endPoint.getY(); paramPaint.setColor(getColor()); paramPaint.setStrokeWidth(paramFloat1 + f4 * f1); paramCanvas.drawPoint(f8, f9, paramPaint); } } public int getColor() { return this.mColor; } public Point getControlPointOne() { return this.controlPointOne; } public Point getControlPointTwo() { return this.controlPointTwo; } public int getDrawSteps() { return this.drawSteps; } public Point getEndPoint() { return this.endPoint; } public Point getStartPoint() { return this.startPoint; } public void setColor(int paramInt) { this.mColor = Color.BLACK; } public void setControlPointOne(Point paramPoint) { this.controlPointOne = paramPoint; } public void setControlPointTwo(Point paramPoint) { this.controlPointTwo = paramPoint; } public void setDrawSteps(int paramInt) { this.drawSteps = paramInt; } public void setEndPoint(Point paramPoint) { this.endPoint = paramPoint; } public void setStartPoint(Point paramPoint) { this.startPoint = paramPoint; } 

}

+19
java android paint bezier handwriting
May 9 '13 at 6:37
source share
4 answers

Change the draw method in the Bezier class to:

 public void draw(Canvas canvas, Paint paint, float startWidth, float endWidth) { float originalWidth = paint.getStrokeWidth(); float widthDelta = endWidth - startWidth; for (int i = 0; i < drawSteps; i++) { float t = ((float) i) / drawSteps; float tt = t * t; float ttt = tt * t; float u = 1 - t; float uu = u * u; float uuu = uu * u; float x = uuu * startPoint.x; x += 3 * uu * t * getControlPointOne().x; x += 3 * u * tt * getControlPointTwo().x; x += ttt * endPoint.x; float y = uuu * startPoint.y; y += 3 * uu * t * getControlPointOne().y; y += 3 * u * tt * getControlPointTwo().y; y += ttt * endPoint.y; paint.setStrokeWidth(startWidth + ttt * widthDelta); canvas.drawPoint(x, y, paint); } paint.setStrokeWidth(originalWidth); } 
+2
Jun 12 '13 at 20:24
source share

You need to see how many points are drawn in the Bezier class and add them.

From your code: you collect 4 points and draw a Bezier curve above them. This means that the algorithm - by design - will miss half of the selected points.

Other options: 1. Create your own Bezier curve or lower order (say, order 3) - and then you will miss only 1/3 points. This view makes the problem useless, since you want to save less data than the sample. 2. Create a Bezier Bezier curve that can approximate the entire signature.

However, you can try to figure out which points you want to select to get a Bezier curve that is closer to the signature: select the top of the letter "l" as the end point of one Bezier curve and the start of the other will give better results.

+1
May 17 '13 at 6:16
source share

You can use simple

the code

 public class MySignatureView extends View { private Path mPath; private Paint mPaint; private Bitmap mBitmap; private Canvas mCanvas; private int bgColor; private float curX, curY; private boolean isDragged = false; private static final int TOUCH_TOLERANCE = 4; private static final int STROKE_WIDTH = 2; public MySignatureView(Context context) { super(context); init(); } public MySignatureView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MySignatureView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setFocusable(true); bgColor = Color.WHITE; mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(bgColor ^ 0x00FFFFFF); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(STROKE_WIDTH); } public void setSigColor(int color) { mPaint.setColor(color); } public void setSigColor(int a, int r, int g, int b) { mPaint.setARGB(a, r, g, b); } public void clearSig() { if (mCanvas != null) { mCanvas.drawColor(bgColor); mCanvas.drawPaint(mPaint); mPath.reset(); invalidate(); } } public Bitmap getImage() { return this.mBitmap; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { int bitW = mBitmap != null ? mBitmap.getWidth() : 0; int bitH = mBitmap != null ? mBitmap.getWidth() : 0; if (bitW >= w && bitH >= h) { return; } if (bitW < w) bitW = w; if (bitH < h) bitH = h; Bitmap newBitmap = Bitmap.createBitmap(bitW, bitH, Bitmap.Config.ARGB_8888); Canvas newCanvas = new Canvas(); newCanvas.setBitmap(newBitmap); if (mBitmap != null) { newCanvas.drawBitmap(mBitmap, 0, 0, null); } mBitmap = newBitmap; mCanvas = newCanvas; } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, mPaint); canvas.drawPath(mPath, mPaint); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touchDown(x, y); break; case MotionEvent.ACTION_MOVE: touchMove(x, y); break; case MotionEvent.ACTION_UP: touchUp(); break; } invalidate(); return true; } private void touchDown(float x, float y) { mPath.reset(); mPath.moveTo(x, y); curX = x; curY = y; isDragged = false; } private void touchMove(float x, float y) { float dx = Math.abs(x - curX); float dy = Math.abs(y - curY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(curX, curY, (x + curX) / 2, (y + curY) / 2); curX = x; curY = y; isDragged = true; } } private void touchUp() { if (isDragged) { mPath.lineTo(curX, curY); } else { mPath.lineTo(curX+2, curY+2); } mCanvas.drawPath(mPath, mPaint); mPath.reset(); } } 
+1
Feb 17 '14 at 6:57
source share

You can use this, I also added xml below:

 import java.io.File; import java.io.FileOutputStream; import java.util.Calendar; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.ContextWrapper; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore.Images; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Toast; public class SignatureCapture extends Activity { public LinearLayout mContent; public signature mSignature; public Button mClear, mGetSign, mCancel; public static String tempDir; public int count = 1; public String current = null; public static Bitmap mBitmap; public View mView; public File mypath; private String uniqueId; private EditText yourName; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.signature); // tempDir = Environment.getExternalStorageDirectory() + "/" + // getResources().getString(R.string.external_dir) + "/"; ContextWrapper cw = new ContextWrapper(getApplicationContext()); // File directory = // cw.getDir(getResources().getString(R.string.external_dir), // Context.MODE_PRIVATE); File directory = new File(Environment.getExternalStorageDirectory() + "/GLP_Images"); if (!directory.exists()) directory.mkdir(); // directory is created; // prepareDirectory(); uniqueId = getTodaysDate() + "_" + getCurrentTime(); current = uniqueId + ".png"; mypath = new File(directory, current); mContent = (LinearLayout) findViewById(R.id.linearLayout); mSignature = new signature(this, null); mSignature.setBackgroundColor(Color.WHITE); mContent.addView(mSignature, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); mClear = (Button) findViewById(R.id.clear); mGetSign = (Button) findViewById(R.id.getsign); mGetSign.setEnabled(false); mCancel = (Button) findViewById(R.id.cancel); mView = mContent; // yourName = (EditText) findViewById(R.id.yourName); mClear.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.v("log_tag", "Panel Cleared"); mSignature.clear(); mGetSign.setEnabled(false); } }); mGetSign.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.v("log_tag", "Panel Saved"); // boolean error = captureSignature(); // if(error){ mView.setDrawingCacheEnabled(true); mSignature.save(mView); // Bundle b = new Bundle(); // b.putString("status", "done"); /* * Intent intent = new * Intent(SignatureCapture.this,SigntuareCaptureActivity.class); * // intent.putExtra("imagePath",mypath); * startActivity(intent); //intent.putExtra("status", "done"); * //setResult(RESULT_OK,intent); finish(); // } */ AlertDialog.Builder dialog = new AlertDialog.Builder( SignatureCapture.this); dialog.setMessage("Details saved"); dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog.show(); } }); mCancel.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.v("log_tag", "Panel Canceled"); Bundle b = new Bundle(); b.putString("status", "cancel"); Intent intent = new Intent(); intent.putExtras(b); setResult(RESULT_OK, intent); finish(); } }); } @Override protected void onDestroy() { Log.w("GetSignature", "onDestory"); super.onDestroy(); } // private boolean captureSignature() // { // // boolean error = false; // String errorMessage = ""; // // // if(yourName.getText().toString().equalsIgnoreCase("")) // { // errorMessage = errorMessage + "Please enter your Name\n"; // error = true; // } // // if(error) // { // Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); // toast.setGravity(Gravity.TOP, 105, 50); // toast.show(); // } // // return error; // } private String getTodaysDate() { final Calendar c = Calendar.getInstance(); int todaysDate = (c.get(Calendar.YEAR) * 10000) + ((c.get(Calendar.MONTH) + 1) * 100) + (c.get(Calendar.DAY_OF_MONTH)); Log.w("DATE:", String.valueOf(todaysDate)); return (String.valueOf(todaysDate)); } private String getCurrentTime() { final Calendar c = Calendar.getInstance(); int currentTime = (c.get(Calendar.HOUR_OF_DAY) * 10000) + (c.get(Calendar.MINUTE) * 100) + (c.get(Calendar.SECOND)); Log.w("TIME:", String.valueOf(currentTime)); return (String.valueOf(currentTime)); } private boolean prepareDirectory() { try { if (makedirs()) { return true; } else { return false; } } catch (Exception e) { e.printStackTrace(); Toast.makeText( this, "Could not initiate File System.. Is Sdcard mounted properly?", 1000).show(); return false; } } private boolean makedirs() { File tempdir = new File(tempDir); if (!tempdir.exists()) tempdir.mkdirs(); if (tempdir.isDirectory()) { File[] files = tempdir.listFiles(); for (File file : files) { if (!file.delete()) { System.out.println("Failed to delete " + file); } } } return (tempdir.isDirectory()); } public class signature extends View { private static final float STROKE_WIDTH = 5f; 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 signature(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 save(View v) { Log.v("log_tag", "Width: " + v.getWidth()); Log.v("log_tag", "Height: " + v.getHeight()); if (mBitmap == null) { mBitmap = Bitmap.createBitmap(mContent.getWidth(), mContent.getHeight(), Bitmap.Config.RGB_565); } Canvas canvas = new Canvas(mBitmap); try { FileOutputStream mFileOutStream = new FileOutputStream(mypath); v.draw(canvas); mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream); mFileOutStream.flush(); mFileOutStream.close(); String url = Images.Media.insertImage(getContentResolver(), mBitmap, "title", null); // Log.v("log_tag","url: " + url); // //In case you want to delete the file // boolean deleted = mypath.delete(); // Log.v("log_tag","deleted: " + mypath.toString() + deleted); // //If you want to convert the image to string use base64 // converter } catch (Exception e) { Log.v("log_tag", e.toString()); } } 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(); mGetSign.setEnabled(true); 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: debug("Ignored touch event: " + event.toString()); 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 debug(String string) { } 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); } } } 



 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/header_bg" android:gravity="center" android:text="Signature" android:textColor="@android:color/white" android:textSize="20dp" android:textStyle="bold" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_weight="1" android:layout_height="wrap_content" android:orientation="vertical" /> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/cancel" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight=".30" android:text="Cancel" android:visibility="gone" /> <Button android:id="@+id/clear" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Clear" /> <Button android:id="@+id/getsign" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Save" /> </LinearLayout> </LinearLayout> 
+1
Feb 17 '14 at 9:40
source share



All Articles