I have been working on an Android drawing application, which is meant to draw a Bezier line, based upon user interaction. The user draws the line on the screen and it appears exactly as they have drawn it.
@Override
public boolean onTouchEvent(MotionEvent event) {
touchX = event.getX();
touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawingElement = new DrawingElement(gridType, canvasWidth, canvasHeight);
drawingElement.addPoint(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawingElement.addPoint(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawingElement.addPoint(touchX, touchY);
actualDrawingElement = new DrawPath(gridType, canvasWidth, canvasHeight, drawPaint, paintColor, brushSize);
actualDrawingElement.setDrawingElementType(DrawingElementType.PATH);
actualDrawingElement.setPoints(drawingElement.getPoints());
drawingElement = actualDrawingElement;
actualDrawingElement = null;
finishedElement = true;
break;
default:
return false;
}
//draw the view - will be called after touch event
@Override
protected void onDraw(Canvas canvas) {
if(bgPaint == null) {
bgPaint = new Paint();
bgPaint.setColor(Color.WHITE);
}
canvas.drawRect(0, 0, getWidth(), getHeight(), bgPaint);
Bitmap dbBMP = null;
BitmapSave bitmapSave = getDatabaseHandler().getLastSave();
if(bitmapSave != null) {
dbBMP = bitmapSave.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
} else {
dbBMP = Bitmap.createBitmap((int) getActualWidth(), (int) getActualHeight(), Bitmap.Config.ARGB_8888);
}
Canvas dbCanvas = new Canvas(dbBMP);
DrawPath p;
if(drawingElement != null && drawingElement.getPointCount() > 0) {
actualDrawingElement = new DrawPath(gridType, canvasWidth, canvasHeight, drawPaint, paintColor, brushSize);
actualDrawingElement.setDrawingElementType(DrawingElementType.PATH);
actualDrawingElement.setPoints(drawingElement.getPoints());
p = (DrawPath)actualDrawingElement;
p.draw(dbCanvas);
p = null;
}
if(finishedElement) {
db.addSave(new BitmapSave(dbBMP));
}
canvas.drawBitmap(dbBMP, 0, 0, drawPaint);
if(displayGrid) {
DrawGrid drawGrid = new DrawGrid(gridType, canvasWidth, canvasHeight, bgPaint);
drawGrid.draw(canvas);
}
updateUndoRedoButtons();
}
The above code shows my onDraw and onTouchEvent methods. I moved to using a database to store the bitmaps as I started to get a lot of memory overload errors and it would crash. Previously I had multiple bitmaps in memory for undo/redo inside an ArrayList (would get to max. 3 or 4 before crashing). I would like to have at least 20 undos/redos (in total) in the app.
In the end it is meant to draw multiple lines at the same time, but even one line is slow.
I have tried to abstract a few things happening, eg. the line drawing... It does store the points in a separate class, which it grabs them later on to draw.
Abstracted line drawing method is...
public void draw(Canvas canvas) {
boolean firstRun = true;
Point2D prevPoints = null;
Point2D points = null;
for(Point2D pointGrp : getPoints()) {
points = getCalculatedPoints(pointGrp);
if (firstRun) {
paths.add(new Path());
paths.get(0).moveTo(points.getPosX(), points.getPosY());
} else {
paths.get(0).quadTo(prevPoints.getPosX(), prevPoints.getPosY(), points.getPosX(), points.getPosY());
}
firstRun = false;
prevPoints = points;
}
canvas.drawPath(paths.get(0), getPaint());
}
At this stage "points = getCalculatedPoints(pointGrp);" literally returns the same point it is give. Point2D object just holds pointx, and pointy nothing else. Has no methods other then getters and setters.
Any ideas why this would be running really slow? It only picks up 4 points across a massive line, making it very jagged and straight.