This article describes the Android View refresh mechanism. Share it for your reference, as follows:
1. Overall explanation
In the Android layout system, the parent View is responsible for refreshing and layout displaying the child View; and when the child View needs to be refreshed, the parent View is notified to complete it.
2. Code analysis
1).ViewGroup's addView method, understand the meaning and transmission of parameters
invalidate calls the method of the parent class View
The main thing that the addViewInner method does is
The dispatchAttachedToWindow(AttachInfo, int visibility) method of the view
1).View's invalidate method, this is a process of backtracking from the bottom to the top. The parent view of each layer will refresh its display area and the incoming
Rect does intersection.
void invalidate(boolean invalidateCache) { if (ViewDebug.TRACE_HIERARCHY) { (this, ); } 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 && ) { // fast-track for GL-enabled applications; just invalidate the whole hierarchy // with a null dirty rect, which tells the ViewAncestor to redraw everything (this, null); return; } } if (p != null && ai != null) { final Rect r = ; (0, 0, mRight - mLeft, mBottom - mTop); // Don't call invalidate -- we don't want to internally scroll // our own bounds (this, r);//Calling the method of the subclass completed } } }
2) ViewGrop's invalidateChild method
public final void invalidateChild(View child, final Rect dirty) { ViewParent parent = this; final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { final int[] location = ; // The location of the subview that needs to be refreshed location[CHILD_LEFT_INDEX] = ; location[CHILD_TOP_INDEX] = ; // If the child is drawing an animation, we want to copy this flag onto // ourselves and the parent to make sure the invalidate request goes through final boolean drawAnimation = ( & DRAW_ANIMATION) == DRAW_ANIMATION; // Check whether the child that requests the invalidate is fully opaque final boolean isOpaque = () && !drawAnimation && () != null; // Mark the child as dirty, using the appropriate flag // Make sure we do not set both flags at the same time final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY; do { View view = null; if (parent instanceof View) { view = (View) parent; } if (drawAnimation) { if (view != null) { |= 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 from the child that initiated the invalidate if (view != null && ( & DIRTY_MASK) != DIRTY) { = ( & ~DIRTY_MASK) | opaqueFlag; } parent = (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 according to the position of the parent view (location[CHILD_LEFT_INDEX] - mScrollX, location[CHILD_TOP_INDEX] - mScrollY); final int left = mLeft; final int top = mTop; //Calculate the actual refreshable area if ((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; (0, 0, mRight - location[CHILD_LEFT_INDEX], mBottom - location[CHILD_TOP_INDEX]); return mParent; } } return null; }
The upward traceback process ends until ViewRoot, which refreshes the final refresh area by ViewRoot
public void invalidateChild(View child, Rect dirty) { }
The view tree is initiated by the performTraversals() method of the ViewRoot object. It is worth noting that each time the drawing is initiated, the views of each View tree are not redrawn, but only those views that "need to be redrawn". The variables inside the View class contain a flag bit DRAWN. When the view needs to be redrawn, the flag bit will be added to the View.
Call process :
() start drawing, the functions implemented by the draw() method are as follows:
1. Draw the background of the View
2. Do some preparations for displaying the gradient box (see 5. In most cases, there is no need to change the gradient box)
3. Call onDraw() method to draw the view itself (Every View needs to overload this method, ViewGroup does not need to implement this method)
4. Call dispatchDraw () method to draw a subview (if the View type is not ViewGroup, it does not contain a subview, and there is no need to overload the
Method) It is worth noting that the ViewGroup class has rewritten the function implementation of dispatchDraw() for us, and applications generally do not need to rewrite this
Method, but can overload the parent class function to implement specific functions.
4.1 The dispatchDraw() method will traverse each subview internally and call drawChild() to call back the draw() method of each subview (note that only the "re-drawn" view in this place will call the draw() method). It is worth noting that the ViewGroup class has rewritten dispatch for us
Draw() function implementation, applications generally do not need to rewrite this method, but can overload the parent function to implement specific functions.
For more information about Android related content, please check out the topic of this site:Android development introduction and advanced tutorial》、《Android multimedia operation skills summary (audio, video, recording, etc.)》、《Summary of the usage of basic Android components》、《Android View View Tips Summary》、《Android layout layout tips summary"and"Android control usage summary》
I hope this article will be helpful to everyone's Android programming design.