I put a Log.d() call into the onDraw() of my extended View, so I could see how often and when it's getting called. It gets called upon instantiation of the view, which is not surprising. But then I notice, it gets called on every tap that is handled by onTouchEvent(), even though my code there isn't doing anything remotely related to graphics. However, in the documentation for Views, I can't seem to find anything about when onDraw() is actually called. I'm not really concerned about my particular project here (this doesn't cause a problem for me), I would just like to know if there is a list somewhere or something that shows the order of operations for a View, particularly what causes onDraw() to get called.
问题:
回答1:
AFAIK, a View's onDraw() is called when:
- The view is initially drawn
- Whenever invalidate() is called on the view
Invalidate can be called by you or the system whenever needed. For example, a lot of Views change how they look onTouch, like an EditText getting an outline and cursor, or a button being in the pressed state. Due to this, Views are redrawn on touch.
I agree that it would be nice to have a document that detailed the working of Views, and if one exists and somebody knows where to find it, please let us know.
回答2:
onDraw()
is called when invalidate()
is called.
But you should know for ViewGroups: onDraw()
will not be called like you expect. Rather, onDispatchDraw()
.
However, in a ViewGroup you can call setWillNotDraw(false)
in the constructor to make onDraw()
to be called on invalidate()
.
Take a look at this answer
回答3:
If you set a background drawable for a View, then the View will draw it for you before calling back to its onDraw() method.
onAttachedToWindow () is called when the view is attached to a window. At this point it has a Surface and will start drawing. Note that this function is guaranteed to be called before onDraw(android.graphics.Canvas), however it may be called any time before the first onDraw -- including before or after onMeasure(int, int).
invalidate() mark the area defined by dirty as needing to be drawn. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future.
回答4:
One important thing to keep in mind is that try to minimize calling of invalidate() function with no arguments. Instead try to maximize the invalidate() function with four arguments.As drawing whole view is very expensive.The second variant refreshes only the part of view.
回答5:
Additional to the above: The soft keyboard causes a View.invalidate()-->View.onDraw() sequence after resizing the Window to sensibly accommodate the 'keyboard'. A custom View.onDraw() must leave itself in a state that anticipates this possibility.
Such phenomenum explains why the app you developed and tested on a tablet with a bluetooth keyboard went to the dogs once it reached the real world (-: