3

I have a LinearLayout and I have a custom view:

public class myView extends View  
{
    Rect rects = new Rect(30,30,80,80); 
    Canvas myCanvas;
    @Override
    public void onDraw(Canvas canvas)     
    {
         myCanvas = canvas;
         paint.setColor(Color.RED);
         canvas.drawRect(rects, paint);

    }
    void changeColor()
    {
        paint.setColor(Color.BLUE);
        myCanvas.drawRect(rects, paint);
        myCanvas.invalidate();
    }
}

in MainActiviy I have:

LinearLayout lv = (LinearLayout) View.inflate(this, R.layout.activity_main, null);
drawView = new myView(this);
lv.addView(drawView); 
setContentView(lv);
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener()
{
        @Override
        public void onClick(View v) {
            drawView.changeColor();
        }  
});

After clicking a button I want to change the color of rectangle by calling changeColor. But new rectangle in some other place is created! Can you please help me?

ssantos
  • 16,001
  • 7
  • 50
  • 70
Sara
  • 2,308
  • 11
  • 50
  • 76

1 Answers1

8

You're calling to drawRect twice (before invalidating the view, and on onDraw). Also, there's no need to store a reference to Canvas.


Keep the desired color in a variable, change it and invalidate the view.-

public class myView extends View {

    private Color color = Color.RED;

    Rect rects = new Rect(30,30,80,80); 

    @Override
    public void onDraw(Canvas canvas) {
         paint.setColor(color);
         canvas.drawRect(rects, paint);
    }

    void changeColor() {
        color = Color.BLUE
        invalidate();
    }
}
ssantos
  • 16,001
  • 7
  • 50
  • 70
  • Thanks. If I want to create multiple shape initially then change their colors by click, then when should I draw them for the first time? If I put all in OnDraw then in every invalidate all of them will be drawn again while I may need change of color for one. – Sara Sep 24 '13 at 19:49
  • Well, implementing that scenario depends on several factors, but if the number of shapes is not too large, I guess you should be fine with an array of colors and rects. You'd iterate from 0 to rects.length, and call setColor and drawRect on each iteration. – ssantos Sep 24 '13 at 20:01
  • but if its large it is not good way. correct? How about calling canvas.drawRect(rects, paint); without calling invalidate? – Sara Sep 24 '13 at 20:07
  • Yeah but how do you know select which rectangle will change its color? – ssantos Sep 24 '13 at 20:17
  • save all of them in an array. – Sara Sep 24 '13 at 20:21
  • Ok, but the user is supposed to click on the square he wants to change color? Sorry but I feel I'm missing something of what you're trying to achieve. – ssantos Sep 24 '13 at 20:24
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/37973/discussion-between-sweet-and-ssantos) – Sara Sep 24 '13 at 20:32
  • HI Sara, i know this is really old, but did you figure it out? I have a similar problem, i have an array of rectangles representing a guitar fretboard. i want to change the colour of a rectangle when it's clicked on and then change back to the original colour, but changing the paint colour and invalidating changes all the rectangles. I've searched all over Google but i can't find an answer and am starting to wonder if it's the wrong approach. – Clario Mar 10 '21 at 06:01