SamuSan
SamuSan

Reputation: 65

Android: Drawing multiple paths

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;


}
}

Upvotes: 2

Views: 3043

Answers (1)

neevek
neevek

Reputation: 12148

The problem is that you are drawing paths constructed with the points in the points list repeatedly.

Note that invalidate() call in onTouch, each of this call will trigger a redraw event, which causes onDraw to be called, everything looks fine at this point. The problem is you only did points.clear() on ACTION_DOWN event, but you also should have cleared them on ACTION_MOVE and ACTION_UP events. Instead, you keep all the points collected previously and draw the paths constructed with all those points in onDraw. 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.

Upvotes: 1

Related Questions