Add signature column in the application - java

I'm doing a simple courier system using android. How do I do if at the end of the delivery process client have to sign on the phone as the acknowledgement that they received the courier. How do i can do this using android. Any advice, suggestion is highly appreciated.

Performing a signature consume lots of space and a in phone device small area is not sufficient to take a signature from client at end of delivery process this is my idea.
Generate a list having delivery details.
--> at delivery time on click of delivered item a view opened.
--> in that view client can perform signature.
--> you can save that signature along with delivery details in DB
--> Delete or transfer items from to Deliver list to Delivered items(Which should be your another view approach)
This is my idea to perfor
m that task. For taking signature you can apply paint method and signature methods ask me if you want help on that too. thanks
package com.paintexample;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
public class DrawView extends View {
private static final float STROKE_WIDTH = 5f;
/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
private Paint paint = new Paint();
private Path path = new Path();
/** Optimizes painting by invalidating the smallest possible area. */
private float lastTouchX;
private float lastTouchY;
private final RectF dirtyRect = new RectF();
public DrawView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
/** Erases the signature. */
public void clear() {
path.reset();
// Repaints the entire view.
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;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// Start tracking the dirty region.
resetDirtyRect(eventX, eventY);
// When the hardware tracks events faster than they are delivered,
// the
// event will contain a history of those skipped points.
int historySize = event.getHistorySize();
Logger.debug("historySize : " + historySize);
for (int i = 0; i < historySize; i++) {
float historicalX = event.getHistoricalX(i);
float historicalY = event.getHistoricalY(i);
expandDirtyRect(historicalX, historicalY);
path.lineTo(historicalX, historicalY);
}
// After replaying history, connect the line to the touch point.
// Logger.debug("eventX " + eventX);
// Logger.debug("eventY " + eventX);
//
// Logger.debug("lastTouchX " + lastTouchX);
// Logger.debug("lastTouchY " + lastTouchY);
//
// if (eventX == lastTouchX && eventY == lastTouchY) {
//
// path.addCircle(eventX, eventY, 20, Path.Direction.CW);
//
// }
path.lineTo(eventX, eventY);
break;
default:
Logger.debug("Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
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;
}
/** Called when replaying history to ensure the dirty region includes all
* points. */
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;
}
}
/** Resets the dirty region when the motion event occurs. */
private void resetDirtyRect(float eventX, float eventY) {
// The lastTouchX and lastTouchY were set when the ACTION_DOWN
// motion event occurred.
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}
above is draw class
now add draw view in your activity like this.
//Assigning Drawing Board
drawView = new DrawView(this);
setContentView(view);
drawView.requestFocus();
linearLayout.addView(drawView);
you can your different methods of DrawView class for clear/paint and more enjoy

Related

How to draw a rectangle in android when a user moves finger?

I want to draw a rectangle. The first corner should be the point where user first touches screen. When user moves his finger, it should draw the rectangle. Here's a link that shows a video what I want to do. But I don't understand it and maybe You can help me. I just want to draw that rectangle on a white background not on an image.
My code :
package com.example.androiddrawing;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CanvasView extends View {
private Canvas canvas;
private Paint paint = new Paint();
private Paint paint2 = new Paint();
private Paint paint3 = new Paint();
private Path path = new Path();
private Point point = new Point();
private static List<Path> lines = new ArrayList<Path>();
private static List<Point> points = new ArrayList<Point>();
private float x, x2, xc, xd, x3, x4;
private float y, y2, yc, yd, y3, y4;
private boolean touchStarted = false;
public enum DrawMode {
FreeDrawMode, RectDrawMode
};
public static DrawMode currentDrawMode;
public void setDrawMode(DrawMode newDrawMode) {
this.currentDrawMode = newDrawMode;
}
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint2.setAntiAlias(true);
paint2.setStrokeWidth(5);
paint2.setColor(Color.RED);
paint2.setStyle(Paint.Style.STROKE);
paint2.setStrokeJoin(Paint.Join.ROUND);
paint3.setAntiAlias(true);
paint3.setColor(Color.BLACK);
paint3.setStrokeWidth(10);
paint3.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
for (Path p : lines)
canvas.drawPath(p, paint);
canvas.drawPath(path, paint2);
for (Point point : points)
canvas.drawCircle(point.x, point.y, 0, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
System.out.println(currentDrawMode);
if (currentDrawMode == DrawMode.FreeDrawMode) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Set a new starting point
paint2.setColor(Color.RED);
path = new Path();
path.moveTo(x, y);
touchStarted = true;
break;
// return true;
case MotionEvent.ACTION_MOVE:
// Connect the points
touchStarted = false;
path.lineTo(x, y);
break;
case MotionEvent.ACTION_UP:
if (touchStarted) {
point = new Point();
point.x = (int) x;
point.y = (int) y;
paint2.setColor(Color.BLACK);
points.add(point);
touchStarted = false;
System.out.println("siin");
} else {
System.out.println("seal");
paint2.setColor(Color.BLACK);
lines.add(path);
}
break;
default:
return false;
}
} else if (currentDrawMode == DrawMode.RectDrawMode) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Set a new starting point
paint3.setColor(Color.RED);
//CODE HERE
break;
// return true;
case MotionEvent.ACTION_MOVE:
//CODE HERE
break;
case MotionEvent.ACTION_UP:
//CODE HERE
break;
default:
return false;
}
}
// Makes our view repaint and call onDraw
invalidate();
return true;
}
}
I should write the code where I put the comments //CODE HERE, but I really don't understand, how do I have to draw a rectangle.
You can use the below code. Hope this helps you.
public class DrawSample extends View {
int mStartX;
int mStartY;
int mEndX;
int mEndY;
Paint mPaint = new Paint();
int mSelectedColor = Color.BLACK;
public DrawSample(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mPaint.setColor(mSelectedColor);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);
setFocusable(true);
}
public DrawSample(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mStartX = (int) event.getX();
mStartY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
mEndX = (int) event.getX();
mEndY = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_UP:
mEndX = (int) event.getX();
mEndY = (int) event.getY();
invalidate();
break;
default:
super.onTouchEvent(event);
break;
}
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(mStartX, mStartY, mEndX, mEndY, mPaint);
}
}
You need to keep the start X and Y points, then, when user stop drawing in the MotionEvent.ACTION_UP get the ending X and Y to get 4 corners of the rectangle:
canvas.drawRect(startX, startY, x, y, paint3);
You can find more info about drawRect here and here.
EDIT i dont have nice environment to test it... but I found some errors in your answer:
else if (currentDrawMode == DrawMode.RectDrawMode) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Set a new starting point
paint3.setColor(Color.RED);
startX = event.getX();
startY = event.getY();
break;
// return true;
case MotionEvent.ACTION_MOVE:
endX = event.getX();
endY = event.getY();
canvas.drawRect(startX, startY, endX, endY, paint3);
//invalidate(); // Tell View that the canvas needs to be redrawn
break;
case MotionEvent.ACTION_UP:
paint3.setColor(Color.BLACK);
canvas.drawRect(startX, startY, endX, endY, paint3);
break;
default:
return false;
}
PS: if you want add info to your question edit it, but dont post new answers!!!

How zoom into a Textbox [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I was wondering if it would be possible for my application to zoom into a textbox when selected. Since the application is meant for people who are generally older, I would like this to be a possible option. Also to let you all know, this isn't related to anything about WebView. The application is simply a set of textboxes.
Zoom in When SELECTED? There is a class on github by #JadeByfield89 which extends the EditText and make it pinch Zoomable .
CODE ZoomableEditText:
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
/**
* Created by Jade Byfield on 3/29/2014.
*/
// ImageView that draws a grid on top of it's canvas
public class ZoomEditTextView extends EditText {
// touch tools
private static final int INVALID_POINTER_ID = -1;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
// The Ôactive pointerÕ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private Bitmap mBitmap = null;
private Paint mPaint;
private Path mPath;
private Paint mBitmapPaint;
private Paint mCirclePaint;
private Path mCirclePath;
private Paint mDrawingPaint;
private List<Path> mPaths = new ArrayList<Path>();
private List<Paint> mPaints = new ArrayList<Paint>();
private float mBrushSize = 12.0f;
private Drawable mDrawable;
private Paint mRectPaint;
private Context mContext;
public ZoomEditTextView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
this.mContext = context;
init();
}
public ZoomEditTextView(Context context) {
super(context, null, 0);
this.mContext = context;
init();
// this.setOnTouchListener(new OnTouchListener() {
//
// #Override
// public boolean onTouch(View v, MotionEvent me) {
//
// InputMethodManager imm = (InputMethodManager) mContext
// .getSystemService(mContext.INPUT_METHOD_SERVICE);
// imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
//
// return true;
// }
//
// });
}
private void init() {
// Create our ScaleGestureDetector
mScaleDetector = new ScaleGestureDetector(mContext, new ScaleListener());
// Sets up drawing tools
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mCirclePaint = new Paint();
mCirclePath = new Path();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(Color.CYAN);
mCirclePaint.setStyle(Paint.Style.STROKE);
mCirclePaint.setStrokeJoin(Paint.Join.MITER);
mCirclePaint.setStrokeWidth(4f);
//
mDrawingPaint = new Paint();
mDrawingPaint.setAntiAlias(true);
mDrawingPaint.setDither(true);
mDrawingPaint.setColor(Color.GREEN);
mDrawingPaint.setStyle(Paint.Style.STROKE);
mDrawingPaint.setStrokeJoin(Paint.Join.ROUND);
mDrawingPaint.setStrokeCap(Paint.Cap.ROUND);
mDrawingPaint.setStrokeWidth(mBrushSize);
mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG) ;
mRectPaint.setStyle(Paint.Style.STROKE);
mRectPaint.setColor(Color.WHITE);
mDrawable = mContext.getResources().getDrawable(R.drawable.ic_launcher);
mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(),
mDrawable.getIntrinsicHeight());
// setDrawingCacheEnabled(true);
// buildDrawingCache();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.save();
//
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
// canvas.drawRect(new Rect(0, 0, canvas.getWidth(),
// canvas.getHeight()), mRectPaint);
super.onDraw(canvas);
// mDrawable.draw(canvas);
// if (mBitmap != null && canvas != null) {
// canvas.drawBitmap(mBitmap, mPosX, mPosY, mPaint);
// }
canvas.restore();
}
// Listen for multi-touch drag event and redraw the view accordingly
#Override
public boolean onTouchEvent(MotionEvent event) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(event);
final int action = event.getAction();
switch (action) {
// a touch down
case MotionEvent.ACTION_DOWN: {
// Scale detector is not in progress
if (!mScaleDetector.isInProgress()) {
final float x = event.getX();
final float y = event.getY();
// Save the ID of this pointer
mActivePointerId = event.getPointerId(0);
// Remember where we started
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer
mActivePointerId = event.getPointerId(0);
break;
}
}
case MotionEvent.ACTION_MOVE: {
// Only move the image if the scale detector is not in progress
if (!mScaleDetector.isInProgress()) {
// Find the index of active pointer and save its position
final int pointerIndex = event.findPointerIndex(mActivePointerId);
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
// mBitmap = getDrawingCache();
// Calculate the distance moved
float dx = x - mLastTouchX;
float dy = y - mLastTouchY;
// Move the object
mPosX += dx;
mPosY += dy;
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
// Invalidate to request a redraw
invalidate();
// break;
} /*
* else {
*
* final float gx = mScaleDetector.getFocusX(); final float gy =
* mScaleDetector.getFocusY();
*
* final float gdx = gx - mLastGestureX; final float gdy = gy -
* mLastGestureY;
*
* mPosX += gdx; mPosY += gdy;
*
* invalidate();
*
* mLastGestureX = gx; mLastGestureY = gy;
*
* }
*/
break;
}
case MotionEvent.ACTION_UP: {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(mContext.INPUT_METHOD_SERVICE);
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
// Reset the active pointer id
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
if (event.getPointerCount() >= 2) {
mLastTouchX = event.getX(newPointerIndex);
mLastTouchY = event.getY(newPointerIndex);
}
mActivePointerId = event.getPointerId(newPointerIndex);
} else {
final int tempPointerIndex = event
.findPointerIndex(mActivePointerId);
mLastTouchX = event.getX(tempPointerIndex);
mLastTouchY = event.getY(tempPointerIndex);
}
break;
}
}
return true;
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}

Nested class cannot be resolved to a type

I'm following this tutorial, but after completing step 6, I'm left with an error: "MyGestureDetector cannot be resolved to a type" when I try to instantiate a "new MyGestureDetector()".
Code:
package com.example.rotatingdialer;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
public class MainActivity extends Activity {
private static Bitmap imageOriginal, imageScaled;
private static Matrix matrix;
private ImageView dialer;
private int dialerHeight, dialerWidth;
private GestureDetector detector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// load the image only once
if (imageOriginal == null) {
imageOriginal = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
// initialize the matrix only once
if (matrix == null) {
matrix = new Matrix();
} else {
// not needed, you can also post the matrix immediately to restore the old state
matrix.reset();
}
detector = new GestureDetector(this, new MyGestureDetector());
dialer = (ImageView) findViewById(R.id.imageView_ring);
dialer.setOnTouchListener(new MyOnTouchListener());
dialer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// method called more than once, but the values only need to be initialized one time
if (dialerHeight == 0 || dialerWidth == 0) {
dialerHeight = dialer.getHeight();
dialerWidth = dialer.getWidth();
// resize
Matrix resize = new Matrix();
resize.postScale((float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getWidth(), (float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getHeight());
imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false);
// translate to the image view's center
float translateX = dialerWidth / 2 - imageScaled.getWidth() / 2;
float translateY = dialerHeight / 2 - imageScaled.getHeight() / 2;
matrix.postTranslate(translateX, translateY);
dialer.setImageBitmap(imageScaled);
dialer.setImageMatrix(matrix);
}
}
});
}
/**
* Simple implementation of an {#link OnTouchListener} for registering the dialer's touch events.
*/
private class MyOnTouchListener implements OnTouchListener {
private double startAngle;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startAngle = getAngle(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
double currentAngle = getAngle(event.getX(), event.getY());
rotateDialer((float) (startAngle - currentAngle));
startAngle = currentAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
detector.onTouchEvent(event);
return true;
}
/**
* Simple implementation of a {#link SimpleOnGestureListener} for detecting a fling event.
*/
private class MyGestureDetector extends SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
dialer.post(new FlingRunnable(velocityX + velocityY));
return true;
}
}
/**
* A {#link Runnable} for animating the the dialer's fling.
*/
private class FlingRunnable implements Runnable {
private float velocity;
public FlingRunnable(float velocity) {
this.velocity = velocity;
}
#Override
public void run() {
if (Math.abs(velocity) > 5) {
rotateDialer(velocity / 75);
velocity /= 1.0666F;
// post this instance again
dialer.post(this);
}
}
}
/**
* #return The angle of the unit circle with the image view's center
*/
private double getAngle(double xTouch, double yTouch) {
double x = xTouch - (dialerWidth / 2d);
double y = dialerHeight - yTouch - (dialerHeight / 2d);
switch (getQuadrant(x, y)) {
case 1:
return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
case 2:
return 180 - Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
case 3:
return 180 + (-1 * Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
case 4:
return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
default:
return 0;
}
}
/**
* #return The selected quadrant.
*/
private int getQuadrant(double x, double y) {
if (x >= 0) {
return y >= 0 ? 1 : 4;
} else {
return y >= 0 ? 2 : 3;
}
}
/**
* Rotate the dialer.
*
* #param degrees The degrees, the dialer should get rotated.
*/
private void rotateDialer(float degrees) {
matrix.postRotate(degrees, dialerWidth/2, dialerHeight/2);
dialer.setImageMatrix(matrix);
// dialer.setImageBitmap(Bitmap.createBitmap(imageScaled, 0, 0, imageScaled.getWidth(), imageScaled.getHeight(), matrix, true));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
...did I go wrong somewhere? Thanks!
The simplest way to do this (that is, without refactoring the class structure of these 4 classes (Activity, touch listener, gesture detector, fling runnable)) is to call it as follows. You'll have to move your MyTouchListener instantiation out into a separate declaration, and then you can use that to create a new instance of the MyGestureDetector class:
MyOnTouchListener onTouchListener = new MyOnTouchListener();
detector = new GestureDetector(this, onTouchListener.new MyGestureDetector());
dialer = (ImageView) findViewById(R.id.imageView_ring);
dialer.setOnTouchListener(onTouchListener);

android - how to validate drawing

In my app, the customer has to sign at the end of the process. Below code is how I manage to make it work.
DrawView
public class DrawView
extends View {
private static final float STROKE_WIDTH = 5f;
/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
private Paint paint = new Paint();
private Path path = new Path();
/** Optimizes painting by invalidating the smallest possible area. */
private float lastTouchX;
private float lastTouchY;
private final RectF dirtyRect = new RectF();
public DrawView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
/** Erases the signature. */
public void clear() {
path.reset();
// Repaints the entire view.
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;
// There is no end point yet, so don't waste cycles invalidating.
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
// Start tracking the dirty region.
resetDirtyRect(eventX, eventY);
// When the hardware tracks events faster than they are delivered,
// the
// event will contain a history of those skipped points.
int historySize = event.getHistorySize();
//Logger.debug("historySize : " + historySize);
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:
//Logger.debug("Ignored touch event: " + event.toString());
return false;
}
// Include half the stroke width to avoid clipping.
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;
}
/** Called when replaying history to ensure the dirty region includes all
* points. */
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;
}
}
/** Resets the dirty region when the motion event occurs. */
private void resetDirtyRect(float eventX, float eventY) {
// The lastTouchX and lastTouchY were set when the ACTION_DOWN
// motion event occurred.
dirtyRect.left = Math.min(lastTouchX, eventX);
dirtyRect.right = Math.max(lastTouchX, eventX);
dirtyRect.top = Math.min(lastTouchY, eventY);
dirtyRect.bottom = Math.max(lastTouchY, eventY);
}
}
and I use FrameLayout to show in the app like this.
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
drawView = new DrawView(this);
drawView.requestFocus();
preview.addView(drawView);
It is working fine. My question is how do I do validation for this. Let's say I throw a pop up saying customer hasn't signed yet. please advice.

Signatures in Android

I want to make a class which captures a human signature for my Android app. I have this code so far:
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
long oldTime = 0;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// paint.setColor(Color.BLACK);
// paint.setAntiAlias(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
Path path = new Path();
if (points.size() > 1) {
for (int i = points.size() - 2; i < points.size(); i++) {
if (i >= 0) {
Point point = points.get(i);
if (i == 0) {
Point next = points.get(i + 1);
point.dx = ((next.x - point.x) / 3);
point.dy = ((next.y - point.y) / 3);
} else if (i == points.size() - 1) {
Point prev = points.get(i - 1);
point.dx = ((point.x - prev.x) / 3);
point.dy = ((point.y - prev.y) / 3);
} else {
Point next = points.get(i + 1);
Point prev = points.get(i - 1);
point.dx = ((next.x - prev.x) / 3);
point.dy = ((next.y - prev.y) / 3);
}
}
}
}
boolean first = true;
for (int i = 0; i < points.size(); i++) {
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else {
Point prev = points.get(i - 1);
path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x
- point.dx, point.y - point.dy, point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_UP) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}
return super.onTouchEvent(event);
}
public boolean checkTime() {
//Check if there was an input 400 ms ago
long newTime = System.currentTimeMillis();
long diffirence = newTime - oldTime;
if (oldTime == 0) {
oldTime = System.currentTimeMillis();
return true;
} else if (diffirence <= 400) {
oldTime = System.currentTimeMillis();
return true;
}
return false;
}
}
class Point {
float x, y;
float dx, dy;
#Override
public String toString() {
return x + ", " + y;
}
}
The problem is that the line will connect to the latest point when I start drawing again, even when I stop drawing for a while. This is of course not very useful for capturing human signatures, that's why I created the checkTime method. If you stop drawing for 400ms it returns false, when you start drawing again it will start a new line which is not connected to the old line. I only just don't know how I can implement my method, I tried a lot but the line keeps connecting to the latest point, maybe someone can help me.
It's probably faster to create the path in onTouch and only draw it in onDraw.
Replace onTouch with
Path path = new Path();
int prevx=0;
int prevy=0;
int prevdx=0;
int prevdy=0;
public boolean onTouch(View view, MotionEvent event)
{
int x = event.getX();
int y = event.getY();
int dx = (x-prevx)/3;
int dy = (y-prevy)/3;
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
path.moveTo(x, y);
}
if(event.getAction() == MotionEvent.ACTION_MOVE)
{
path.cubicTo(prevx + prevdx, prevy + prevdy, x - dx, y - dy, x, y);
}
prevx=x;
prevy=y;
prevdx=dx;
prevdy=dy;
invalidate();
return true;
}
onDraw will be just
public void onDraw(Canvas canvas)
{
canvas.drawPath(path, paint);
}
I used this post from Lars Vogel, but many thanks to Marc Van Daele!
This is code wich paints the View:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
public SingleTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
#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);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}
}
You have to call this activity to start paiting:
import android.app.Activity;
import android.os.Bundle;
public class SingleTouchActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SingleTouchEventView(this, null));
}
}

Categories

Resources