Andrzej Dąbrowski
Andrzej Dąbrowski

Reputation: 1209

onDraw called twice when View added dynamically by addView method

I want to add a new View to a Layout dynamically by layout.addView(view) method. The new View is not supposed to be visible, but I want it's Display List to be created so it doesn't have to redraw (call onDraw method) itself when I decide to show it (by animation, for example fade in).

I run this code:

customView = new CustomView(this.getContext());
customView .setAlpha(0.0f);
this.addView(customView ); // 'this' is RelativeLayout instance in this case

onDraw method gets called for customView and everything is fine. However, when I change anything in my layout (push a button, scroll, anything that invalidates layout), the onDraw method for my customView is called second time. After that, it isn't called any more if I don't invalidate my customView (correct behaviour).

I don't know why Android behaves this way. I want it to create customView, call onDraw, create a Display List for it, and not call onDraw any more until I invalidate my view. To sum up, onDraw is supposed to be called once.

And it has nothing to do with initial invisibility of customView, if alpha is set to 0.5f, behaviour is the same.

My question is, how to make Android call onDraw only once?

And if Android really has to call onDraw twice, then what should I do to enforce it to do it in some code right after this.addView(view); without setting up any timers because THAT would be totally ugly.

Upvotes: 2

Views: 2655

Answers (1)

crazyPixel
crazyPixel

Reputation: 2330

The behavior you are describing is ok and is a part of the android framework for view object -

Drawing

Drawing is handled by walking the tree and rendering each view that intersects the invalid region. Because the tree is traversed in-order, this means that parents will draw before (i.e., behind) their children, with siblings drawn in the order they appear in the tree. If you set a background drawable for a View, then the View will draw it for you before calling back to its onDraw() method. Note that the framework will not draw views that are not in the invalid region. To force a view to draw, call invalidate()

(Taken from the official google android API docs).

Meaning your custom view is contained by the same view that contains the button\scrollbar etc. If you don't want it to be rendered everytime the onDraw method is called for the subtree your view resides in you can set the view's boolean flag to false - use setWillNotDraw() to do that.
(you should place it on the activity's onCreate in order to render the view set this flag to false (which is also the default) and use invalidate() whenever you want to render the view).
You can read the official google docs for further information.

Upvotes: 2

Related Questions