Android : onTouch event and ragged track of finger movement (it is not smooth issue)

on Tuesday, November 11, 2014


I made simple application for drawing via finger on a tablet.


When I touch and move the finger fast then I get a ragged line.


When I turn on the OS pointer tracking (Android 4.2.2: Settings->Developer options->(Input) Pointer location) the track of the OS pointer location is not ragged. Moreover, when I open application and drawing, the track from OS pointer location is not covered with track from application!


onTouch event and OS pointer location is not the same event?


When I look on ragged curve I saw additional points according to OS pointer location. These additional points are corrupted? How I can filtered it? I use only MotionEvent.ACTION_MOVE event.


Please look (bottom left curves): Ragged track nad not covered with OS pointer location


Source code: TouchDrawExamples-src.tar.gz


Ready to install and run: TouchDrawExamples.apk


Another screen shots: nocovered2.png nocovered3.png



package pl.edu.pk.iti.examples.touch;

import android.app.Activity;
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.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

public class FingerPaintActivity extends Activity {

DrawingView dv;
private Paint mPaint;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(dv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(2);
}

public class DrawingView extends View {

public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;

public DrawingView(Context c) {
super(c);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);

}

@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);
}

private void touch_move(float x, float y) {
mPath.lineTo(x, y);
}

private void touch_up() {
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) {
if (event.getAction() != MotionEvent.ACTION_DOWN &&
event.getAction() != MotionEvent.ACTION_UP &&
event.getAction() != MotionEvent.ACTION_MOVE) {
return false;
}

boolean first = false;
boolean last = false;

if (event.getAction() == MotionEvent.ACTION_DOWN) {
first = true;
}

if (event.getAction() == MotionEvent.ACTION_UP) {
last = true;
}

for (int i = 0; i < event.getHistorySize(); i++) {
drawPoint(event.getHistoricalX(i), event.getHistoricalY(i), first, false);
first = false;
}

drawPoint(event.getX(), event.getY(), first, last);

invalidate();
return true;
}

private void drawPoint(float x, float y, boolean first, boolean last) {
if (first) {
touch_start(x, y);
} else if (last) {
touch_move(x, y);
touch_up();
} else {
touch_move(x, y);
}
}
}
}

0 comments:

Post a Comment