Reputation: 16603
I'd like to be notified after the view finishes redrawing after I ask it to invalidate. As said in this answer, the invalidate()
method doesn't call a View's onDraw()
the UI immediately, but schedules the repaint in a message queue which is executed after when the main thread is idle.
I'd like to show a progress dialog, do some UI modifications and then dismiss the dialog when the view is drawn properly. Is there some trick that I can do to know when the View was drawn? Maybe by subclassing the view, overriding the onDraw()
method?
Upvotes: 3
Views: 7949
Reputation: 5702
I think you answered your question yourself. Why not:
public class DrawListenerView extends View{
private Callback callback;
public DrawListenerView(Callback callback){
this.callback = callback;
}
@Override
protected void onDraw (Canvas canvas){
super.onDraw(canvas);
//add your method here you want to call
//Or use a Callback-pattern
callback.finish();
}
}
public interface Callback(){
public void finish();
}
If you look at the Source:
The comment above says
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will >be called at some point in the future. This must be called from a UI thread. To call from >a non-UI thread, call postInvalidate().
Try it :)
Edit: probably you want to use a Callback to handle this.
Upvotes: 5
Reputation: 28932
You're finding it strange to try to do this because you're going about it all wrong. ;)
You're talking about wanting to wait to dismiss a dialog until something is finished drawing. That implies that you have a drawing operation that is long enough that you want to wait for it.
Drawing a frame in onDraw should be fast. You have 16 milliseconds per frame to do any sort of input processing and drawing if you want to hit 60fps and have a smooth UI. Drawing should never take long enough that you would want to show a progress dialog while it's finishing. (Aside from that, drawing as a result of invalidating part of your UI blocks your UI thread, and your progress dialog wouldn't illustrate any progress until it's done anyway.)
If you need to do some complex off-screen rendering to show later, you should do it in an AsyncTask or similar off of your UI thread, not in a view's actual onDraw method. Once you get the finished callback from that, you can quickly draw the prerendered image you just created and dismiss your progress dialog.
Upvotes: 4