This example describes the Android view refresh mechanism. Share to everyone for your reference, specific as follows:
I. GENERAL description
In Android's layout system, the parent view is responsible for refreshing, layout, and displaying child view, and when the child view needs to be refreshed, notify the parent view to complete.
Second, code Analysis
1). ViewGroup AddView method to understand the meaning and transfer of parameters
Invalidate method of calling parent view
The main thing the Addviewinner method does is
View's Dispatchattachedtowindow (attachinfo info, int visibility) method
1). View's Invalidate method, which is a process of backtracking up from the bottom, each layer's parent view will display its own area with the incoming refresh
Rect do the intersection.
void Invalidate (Boolean Invalidatecache) {if (viewdebug.trace_hierarchy) {viewdebug.trace (this, Viewdebug.hie
Rarchytracetype.invalidate);
} if (Skipinvalidate ()) {return; if (Mprivateflags & Drawn | has_bounds) = = (Drawn |
Has_bounds) | |
(Invalidatecache && (mprivateflags & drawing_cache_valid) = Drawing_cache_valid) | | (Mprivateflags & invalidated)!= invalidated | |
Isopaque ()!= mlastisopaque) {mlastisopaque = Isopaque ();
Mprivateflags &= ~drawn;
Mprivateflags |= DIRTY;
if (invalidatecache) {mprivateflags |= invalidated;
Mprivateflags &= ~drawing_cache_valid;
Final Attachinfo ai = mattachinfo;
Final viewparent p = mparent; Noinspection pointlessbooleanexpression,constantconditions if (!
Hardwarerenderer.render_dirty_regions) {if (P!= null && ai!= null && ai.mhardwareaccelerated) { fast-Track for gl-enabled applications;
Just invalidate the whole hierarchy//with a null dirty rect, which tells the viewancestor to redraw everything
P.invalidatechild (this, null);
Return
} if (P!= null && AI!= null) {final Rect r = ai.mtmpinvalrect;
R.set (0, 0, Mright-mleft, mbottom-mtop); Don ' t call invalidate--we don ' t want to internally scroll//Our own bounds-p.invalidatechild (this, R
//Call subclass method Complete}}
2) The Invalidatechild method for Viewgrop
Public final void Invalidatechild (View child, final Rect dirty) {viewparent parent = this;
Final Attachinfo attachinfo = Mattachinfo;
if (attachinfo!= null) {final int[] location = attachinfo.minvalidatechildlocation;
The position of the child view that needs to be refreshed location[child_left_index] = Child.mleft;
Location[child_top_index] = child.mtop; If the is drawing a animation, we want to copy this flag onto//ourselves and the parent to make sure the I Nvalidate request goes through final Boolean drawanimation = (Child.mprivateflags & draw_animation) = = Draw_animat
ION; Check whether the child this requests the invalidate is fully opaque final Boolean isopaque = Child.isopaque ()
;&!drawanimation && child.getanimation ()!= null; Mark the child as dirty, using the appropriate flag//Make sure we don't set both flags at the same time Fina l int opaqueflag = Isopaque?
Dirty_opaque:dirty;
Do {view view = null; if (parent instanceof view) {view = (view) parent;
} if (drawanimation) {if (view!= null) {view.mprivateflags |= draw_animation;
else if (parent instanceof Viewroot) {(viewroot) parent). Misanimating = true; }//If the parent is dirty opaque or not dirty, mark it dirty with the opaque//flag coming The child that initiated the invalidate if (view!= null && (View.mprivateflags & Dirty_mask)!= DIRTY)
{view.mprivateflags = (view.mprivateflags & ~dirty_mask) | Opaqueflag;
Parent = parent.invalidatechildinparent (location, dirty);
while (parent!= null); } public viewparent Invalidatechildinparent (final int[] location, final Rect dirty) {if (Mprivateflags & Drawn) = = drawn) {if (Mgroupflags & Flag_optimize_invalidate | Flag_animation_done)!= flag_optimize_invalidate) {//Offset refresh area based on location of parent view
Dirty.offset (Location[child_left_index]-MSCROLLX, Location[child_top_index]-mscrolly);
Final int left = Mleft;
Final int top = Mtop;
Calculates the actual refresh area if (dirty.intersect (0, 0, mright-left, mbottom-top) | |
(Mprivateflags & draw_animation) = = draw_animation) {mprivateflags &= ~drawing_cache_valid;
Location[child_left_index] = left;
Location[child_top_index] = top;
return mparent;
} else {mprivateflags &= ~drawn & ~drawing_cache_valid;
Location[child_left_index] = Mleft;
Location[child_top_index] = mtop;
Dirty.set (0, 0, Mright-location[child_left_index], Mbottom-location[child_top_index]);
return mparent;
} return null;
}
This process of backtracking up to the end of the Viewroot, which is refreshed by viewroot on this final refresh area
Viewroot.java
public void Invalidatechild (View child, Rect dirty) {
}
The draw () method is invoked by the Performtraversals () method of the Viewroot object to initiate the drawing of the view tree, and it is noteworthy that each view of the view tree is not redrawn each time the drawing is initiated, but only those views that need to be redrawn are redrawn. The view class internal variable contains a flag bit drawn that will be added to the view when it needs to be redrawn.
Call Process :
Mview.draw () starts drawing, and the Draw () method implements the following functions:
1. Draw the background of the view
2, to show the gradient box to do some preparatory operations (see 5, in most cases, do not need to change the gradient box)
3, call the OnDraw () method to draw the view itself (each view needs to overload the method, ViewGroup do not need to implement the method)
4, call the Dispatchdraw () method to draw a child view (if the view type is not viewgroup, that is, do not include a child view, you do not need to overload the
method) It is worth noting that the ViewGroup class has rewritten the Dispatchdraw () feature implementation for us, and the application generally does not need to override the
method, but you can overload the parent class function to implement specific functionality.
The 4.1 Dispatchdraw () method iterates through each child view, calling Drawchild () to recall the draw () method of each child view (note that the draw () method is invoked by the "redraw" view of this place). It is worth noting that the ViewGroup class has rewritten the dispatch for us
Draw () is implemented, applications generally do not need to override this method, but the parent class function can be overloaded to implement specific functionality.
For more information on Android-related content readers can view the site topics: "Android Development Introduction and Advanced Course", "Android Multimedia operating skills Summary (audio, video, recording, etc.)", "Android Basic Components Usage Summary", " Android View tips Summary, Android layout layout tips and a summary of Android controls usage
I hope this article will help you with the Android program.