[Android FrameWork 6.0 source code learning] addView function analysis of ViewGroup, viewgroupaddview

Source: Internet
Author: User

[Android FrameWork 6.0 source code learning] addView function analysis of ViewGroup, viewgroupaddview

In Android, the entire View is assembled in a combination mode.

ViewGroup is equivalent to the root of the tree. Layout is equivalent to the branches, and the View of each seed is equivalent to the leaves.

View class. Let's take it as a seed. Haha!

ViewGroup belongs to the root of a tree and can grow many branches (inherited from custom Layout), while many leaves can grow on the branches (TextView, ImageVIew ......)

Well, let's talk less about it. Next, let's get started!

First, the View operation method is defined in an interface called ViewManager. There are two methods in the interface: Remove and update.

public interface ViewManager    {        /**         * Assign the passed LayoutParams to the passed View and add the view to the window.         * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming         * errors, such as adding a second view to a window without removing the first view.         * <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a         * secondary {@link Display} and the specified display can't be found         * (see {@link android.app.Presentation}).         * @param view The view to be added to this window.         * @param params The LayoutParams to assign to view.         */        public void addView(View view, ViewGroup.LayoutParams params);        public void updateViewLayout(View view, ViewGroup.LayoutParams params);        public void removeView(View view)  }

AddView is implemented in ViewGroup, and then code is pasted for analysis.

    public void addView(View child, LayoutParams params) {        addView(child, -1, params);    }

In this method, the addView method is called and another-1 is passed. This-1 is the View index and the location to be inserted.

    public void addView(View child, int index, LayoutParams params) {        if (DBG) {            System.out.println(this + " addView");        }        if (child == null) {            throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");        }        // addViewInner() will call child.requestLayout() when setting the new LayoutParams        // therefore, we call requestLayout() on ourselves before, so that the child's request        // will be blocked at our level        requestLayout();        invalidate(true);        addViewInner(child, index, params, false);    }

 

This method re-draws the layout, and then calls addViewInner (child, index, params, false); Method to insert the View to the corresponding position.

Private void addViewInner (View child, int index, LayoutParams params, boolean preventRequestLayout) {if (mTransition! = Null) {// Don't prevent other add transitions from completing, but cancel remove // transitions to let them complete the process before we add to the container mTransition. cancel (LayoutTransition. DISAPPEARING);} if (child. getParent ()! = Null) {throw new IllegalStateException ("The specified child already has a parent. "+" You must call removeView () on the child's parent first. ");} if (mTransition! = Null) {mTransition. addChild (this, child) ;}if (! CheckLayoutParams (params) {params = generateLayoutParams (params);} if (preventRequestLayout) {child. mLayoutParams = params;} else {child. setLayoutParams (params);} if (index <0) {index = mChildrenCount;} // ViewGroup maintains the sub-View with a view array, this method adds the view to the response location addInArray (child, index); // bind the parent container of the inserted view to the current group // tell our children if (preventRequestLayout) {child. assignParent (this);} else {Child. mParent = this;} if (child. hasFocus () {requestChildFocus (child, child. findFocus ();} AttachInfo ai = mAttachInfo; if (ai! = Null & (mGroupFlags & FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW) = 0) {boolean lastKeepOn = ai. mKeepScreenOn; ai. mKeepScreenOn = false; child. dispatchAttachedToWindow (mAttachInfo, (mViewFlags & VISIBILITY_MASK); if (ai. mKeepScreenOn) {needGlobalAttributesUpdate (true);} ai. mKeepScreenOn = lastKeepOn;} if (child. islayoutdireinherited () {child. resetRtlProperties ();} dispatchViewAdded (chi Ld); if (child. mViewFlags & DUPLICATE_PARENT_STATE) = DUPLICATE_PARENT_STATE) {mGroupFlags | = flag_policy_children_on_drawable_state_change;} if (child. hasTransientState () {childHasTransientStateChanged (child, true);} if (child. getVisibility ()! = View. GONE) {policysubtreeaccessibilitystatechangedifneeded ();} if (mTransientIndices! = Null) {final int transientCount = mTransientIndices. size (); for (int I = 0; I <transientCount; ++ I) {final int oldIndex = mTransientIndices. get (I); if (index <= oldIndex) {mTransientIndices. set (I, oldIndex + 1 );}}}}

 

This method first checks LayoutParams to see whether the inserted view has a length and width. If not, a default LayoutParams is generated.

Then, judge whether the index is less than 0. If it is less than 0, the value is assigned to the number of containers in the current container, which indicates that the index is inserted to the last one.

Then, call the addInArray method to insert the View to the current ViewGroup. After the insertion is complete, bind the view to the parent container (the value of getParent)

Then there will be some focus, the distribution of the listener. Let's analyze the insertion method carefully, that is, addInArray.

 

   private void addInArray(View child, int index) {        View[] children = mChildren;        final int count = mChildrenCount;        final int size = children.length;        if (index == count) {            if (size == count) {                mChildren = new View[size + ARRAY_CAPACITY_INCREMENT];                System.arraycopy(children, 0, mChildren, 0, size);                children = mChildren;            }            children[mChildrenCount++] = child;        } else if (index < count) {            if (size == count) {                mChildren = new View[size + ARRAY_CAPACITY_INCREMENT];                System.arraycopy(children, 0, mChildren, 0, index);                System.arraycopy(children, index, mChildren, index + 1, count - index);                children = mChildren;            } else {                System.arraycopy(children, index, children, index + 1, count - index);            }            children[index] = child;            mChildrenCount++;            if (mLastTouchDownIndex >= index) {                mLastTouchDownIndex++;            }        } else {            throw new IndexOutOfBoundsException("index=" + index + " count=" + count);        }    }

 

 

 

MChildren is a View-type array in the ViewGroup, which stores all the sub-views in the Group.

The value of the constant ARRAY_CAPACITY_INCREMENT is 12.

First, determine whether the mChildren location is sufficient. If not, expand the 12 locations, copy the source array content to the new array, and then put the view to be added to the end.

If the index is smaller than the count value, it indicates an insert operation. It also determines whether the location is sufficient. If not, it expands and copies the data to the index, and then copies the remaining data to the index + 1 to the end.

In this way, the index position is empty. The insert operation is complete.

After the insertion is complete, the system redraws the interface and you can see the inserted view.

 

The addView method is completely analyzed. If you have any questions, you can point it out. The same is true for errors. Learn and make progress together.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.