I’m trying to develop a simple “draw-on-touch” and I want to draw the different paths that the user places in an onTouch listener.
I’ve got a simple problem. When I draw the paths I obtain a single path drawn in the points of the last onTouch entry.
I think the paths are all drawn over the last path because I use a Paint with a 150 alpha and it looks more solid in the second and succesive onTouch entries.
How could I solve that? Thanks!
public class PaintView extends View implements OnTouchListener {
List<List<Point>> paths = new ArrayList<List<Point>>();
List<Point> points = new ArrayList<Point>();
Paint paintLine = new Paint();
Paint paintCircle = new Paint();
public PaintView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
paintLine.setStyle(Paint.Style.STROKE);
paintLine.setStrokeWidth(10);
paintLine.setColor(Color.GREEN);
paintLine.setAlpha(150);
}
public void onDraw(Canvas canvas) {
Path path = new Path();
List<Point> pointsList;
List<Path> pathList = new ArrayList<Path>();
Point point = new Point();
for (int i = 0; i < paths.size(); i++) {
pointsList = paths.get(i);
path.reset();
boolean first = true;
for (int j = 0; j < points.size(); j+=2 ) {
point = pointsList.get(j);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (j < pointsList.size() - 1 ) {
Point nextPoint = pointsList.get(j+1);
path.quadTo(point.x, point.y, nextPoint.x, nextPoint.y);
} else {
path.lineTo(point.x, point.y);
}
}
pathList.add(path);
}
for (Path pathDraw : pathList) {
canvas.drawPath(pathDraw, paintLine);
}
}
public boolean onTouch(View view, final MotionEvent event) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// DO SOMETHING
points.clear();
points.add(point);
break;
case MotionEvent.ACTION_MOVE:
points.add(point);
break;
case MotionEvent.ACTION_UP:
points.add(point);
paths.add(points);
break;
default:
return false;
}
invalidate();
return true;
}
}
The problem is that you are drawing paths constructed with the points in the
pointslist repeatedly.Note that
invalidate()call inonTouch, each of this call will trigger a redraw event, which causesonDrawto be called, everything looks fine at this point. The problem is you only didpoints.clear()onACTION_DOWNevent, but you also should have cleared them onACTION_MOVEandACTION_UPevents. Instead, you keep all the points collected previously and draw the paths constructed with all those points inonDraw. So you are effectively drawing repeatedly some of the paths constructed with the points collected previously.Note in a drag motion, there will be 1 ACTION_DOWN, N ACTION_MOVE, 0 or 1 ACTION_UP events.