dinesh707
dinesh707

Reputation: 12582

Canvas do not update (invalidate) until whole while loop ends

I'm trying to move a ball on canvas. a and b are similar to x,y coordinate positions. Any way from my code im trying to get different values dynamically. The a,b are global variables. But it seems that "invalidate()" or the refreshing of screen only happens afer end of the whole loop. Do you know why?. And if i have to build this on another thread please suggest me with some simple codes.

private void shootBall(){
    while (a>b){
        a = getPositionX();
        b = getPositionY();
        invalidate();
        }
    }
}

Upvotes: 3

Views: 8095

Answers (4)

Wasim Ahmed
Wasim Ahmed

Reputation: 356

UI cant be modified form any new thread..you should use invalidate() in the same thread where your view

Upvotes: 0

Lumis
Lumis

Reputation: 21639

You can put invalidate() at the end of onDraw() like in this example: How can I use the animation framework inside the canvas?

However this works well on some devices while bottlenecks and slows down on other.

To use a thread and SurfaceView go through all of these tutorials: http://www.droidnova.com/playing-with-graphics-in-android-part-i,147.html

Upvotes: 0

cidermonkey
cidermonkey

Reputation: 306

do it like this, and use postInvalidate() instead:

private void shootBall(){

    new Thread(new Runnable() {
        public void run() {

            while (a>b){
                a = getPositionX();
                b = getPositionY();
                postInvalidate();
            }

        }
    }).start();
}

edit: but as mentioned before, don't assume that the invalidate redraws the screen, it marks it as to-be-redrawn and the UI thread will get around to it.

Upvotes: 2

Chet Haase
Chet Haase

Reputation: 1111

I think it's more correct to say that you can call invalidate() from within a loop, but that that invalidation will not be handled (the canvas won't be redrawn) until after your loop is complete. The problem is that you are calling invalidate on the same thread (the UI toolkit thread) as the one that would call your onDraw() method. So unless/until you hand control back to the toolkit, it cannot possibly do the rendering. So your invalidate() call does actually invalidate the view ... but the view won't be redrawn until after your loop completes and your function returns.

It is more correct to change the position in some function that is called via some timer (which is essentially what the animation classes do). In that function, you would change the values, invalidate() appropriately, and return. Then the toolkit re-renders the scene and your function will get future callbacks and update the position accordingly.

Upvotes: 12

Related Questions