Zach
Zach

Reputation: 10129

Change the color of already drawn polygonal path

I have drawn a polygonal path based on user finger movement using the code given below.

paint = new Paint();
    strokePaint = new Paint();
    //paint.setColor(Color.RED);
    paint.setARGB(125, 255, 0, 0);
    paint.setStyle(Style.FILL);
    paint.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));
    paint.setStrokeWidth(5);
    paint.setAntiAlias(true);
    wallpath = new Path();

and on onDraw i am using this code to draw the figure

wallpath.lineTo(endPoint.x, endPoint.y);
        canvas.drawPath(wallpath, paint);

The above code is working fine. But on double tap i want to change the fill color. For that I am using this code

paint.setARGB(125, 225, 0, 0);
        paint.setStyle(Style.FILL);
        paint.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));
        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
        invalidate();

But it doesnt seems to be working. How can I do this properly?

Complete code for reference

public class HotspotView extends View
{

    private Paint paint,strokePaint;
    private PointF startPoint, endPoint;
    private boolean isDrawing,isFinished,isAnimating,isRecording,isRedrawing;
    private Path wallpath;
    private ArrayList<PointF> points;
    private RectF rectF;
    private CurlView curlView;
    public int imageWidth;
    private String fileName;
    private AudioRecorder audioRecorder;
    private GestureDetector gestureDetector;
    public static int LONG_PRESS_TIME = 500; // Time in miliseconds 
    private AudioPlayer player;

    final Handler _handler = new Handler(); 
    Runnable _longPressed = new Runnable() { 
        public void run() {
            Log.i("info","LongPress");
            isRecording = true;
            isDrawing = false;
            isRedrawing = true;
            ///////////////////******************///////////////////////
            //paint = new Paint();
            //strokePaint = new Paint();
            //paint.setColor(Color.RED);
            paint.setARGB(125, 225, 0, 0);
            paint.setStyle(Style.FILL);
            paint.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));
            paint.setStrokeWidth(5);
            paint.setAntiAlias(true);
            invalidate();
            //////////////////*****************////////////////////////
            audioRecorder = new AudioRecorder(fileName);
            setFileName();
            audioRecorder.startRecording(fileName);
        }   
    };

    public HotspotView(Context context)
    {
        super(context);
        init();
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public HotspotView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init();
        gestureDetector = new GestureDetector(context, new GestureListener());
    }
    public HotspotView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    private void init()
    {
        isRecording = false;
        isRedrawing = false;
        paint = new Paint();
        strokePaint = new Paint();
        //paint.setColor(Color.RED);
        paint.setARGB(125, 255, 0, 0);
        paint.setStyle(Style.FILL);
        paint.setPathEffect(new DashPathEffect(new float[] {10,20}, 0));
        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
        wallpath = new Path();
        points = new ArrayList<PointF>();
        rectF = new RectF();
        rectF.set(-1.7883435f, 1.0f, 1.7883435f, -1.0f);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {

        if(isAnimating)
        {
            PointF point = this.translate(points.get(0));
            if(wallpath == null)
            {
                wallpath = new Path();
            }
            wallpath.moveTo(point.x, point.y);
            isDrawing = false;
            isFinished = false;
            for(int i=1;i<points.size();i++)
            {
                if(isRedrawing)
                {
                    point = points.get(i);
                }
                else
                {
                    point = this.translate(points.get(i));
                }

                wallpath.lineTo(point.x, point.y);
                //Log.d("Points", "X = "+point.x);
                //Log.d("Points", "Y = "+point.y);
                canvas.drawPath(wallpath, paint);
            }
            if(isRedrawing)
            {
                point = points.get(0);
            }
            else
            {
                point = this.translate(points.get(0));
            }

            wallpath.lineTo(point.x, point.y);
            canvas.drawPath(wallpath, paint);
            isFinished = true;
        }
        else if(isDrawing)
        {
            //canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint);

            wallpath.lineTo(endPoint.x, endPoint.y);
            canvas.drawPath(wallpath, paint);
        }

        if(isFinished)
        {
            //wallpath.lineTo(endPoint.x, endPoint.y);
            //canvas.drawPath(wallpath, strokePaint);
            wallpath.close();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        boolean result = gestureDetector.onTouchEvent(event);//return the double tap events

        if(!isAnimating)
        {

            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    isDrawing = true;
                    //wallpath.reset();
                    _handler.postDelayed(_longPressed, LONG_PRESS_TIME);
                    startPoint = new PointF(event.getX(), event.getY());
                    endPoint = new PointF();

                    endPoint.x = event.getX();
                    endPoint.y = event.getY();
                    wallpath.moveTo(endPoint.x,endPoint.y);
                    points.add(startPoint);
                   //invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    PointF point = new PointF(event.getX(),event.getY());
                    endPoint.x = event.getX();
                    endPoint.y = event.getY();
                    double distance = Math.sqrt(Math.pow((endPoint.x - startPoint.x), 2)+ Math.pow(endPoint.y - startPoint.y,2));
                    if(distance >2)
                    {
                        _handler.removeCallbacks(_longPressed);
                        if(!isRecording)
                        {

                            if(isDrawing)
                            {

                                Log.d("Point", "X = "+(event.getX() - this.getLeft()));
                                Log.d("Point", "Y = "+(event.getY() - this.getTop()));
                                points.add(point);
                                invalidate();
                            }

                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    _handler.removeCallbacks(_longPressed);
                    if(isRecording)
                    {
                        audioRecorder.stopRecording();
                        isRecording = false;
                    }

                    if(isDrawing)
                    {
                        endPoint.x = startPoint.x;//event.getX();
                        endPoint.y = startPoint.y;//event.getY();
                        strokePaint.setARGB(255, 255, 0, 0);
                        strokePaint.setStyle(Style.STROKE);
                        strokePaint.setPathEffect(new DashPathEffect(new float[] {5,10}, 0));
                        strokePaint.setStrokeWidth(5);
                        strokePaint.setAntiAlias(true);
                        isFinished = true;
                        invalidate();
                        //isDrawing = false;
                    }
                    break;
                default:
                    break;
            }
        }

        return result;
    }

Upvotes: 1

Views: 712

Answers (2)

Chiral Code
Chiral Code

Reputation: 1436

It would be helpful if you could post some more code from your onDraw method, because it's hard to say what is called when.

My guess is that invalidate works fine, but each time when onDraw is called, you reset your paint settings (paint = new Paint()), so paint with different color is simply not used.

EDIT:

I can't tell you in which exact line you have a bug, however in my opinion it's not related to path or paint settings. There are too many state flags (isDrawing, isFinished, isAnimating, isRecording, isRedrawing) in your code and you can't control it anymore.

OnDraw method should simply draw points:

@Override
protected void onDraw(Canvas canvas) {
    if (points.size() > 0) {
        PointF point = points.get(0);
        wallpath.rewind();
        wallpath.moveTo(point.x, point.y);
        for (int i = 1; i < points.size(); i++) {
            point = points.get(i);
            wallpath.lineTo(point.x, point.y);
        }
        canvas.drawPath(wallpath, paint);
    }
}

Simplify your code. Just for a test: replace your onDraw method with my proposition and you'll see that path will change color on long press.

Upvotes: 1

sergej shafarenka
sergej shafarenka

Reputation: 20416

To fill a Path you need to close it first. Call Path.close() to close the current contour.

If you want to change color of the lines, you need to use paint.setStyle(Paint.Style.STROKE) and use paint.setColor() with it.

... and of course you need to invalidate your view, that onDraw() - where you draw your path - is called again.

Upvotes: 1

Related Questions