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):
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