LayoutInflater source code parsing and layoutinflater source code

Source: Internet
Author: User

LayoutInflater source code parsing and layoutinflater source code

Android uses LayoutInflater for layout loading. There are two methods to obtain LayoutInflater:

First:

LayoutInflater layoutInflater = LayoutInflater.from(context); 

Second:

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

From the source code, we can see that the first is the second encapsulation simplification, which is easy to use:

1 public static LayoutInflater from(Context context) {2         LayoutInflater LayoutInflater =3                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);4         if (LayoutInflater == null) {5             throw new AssertionError("LayoutInflater not found.");6         }7         return LayoutInflater;8     }

We can load the layout by calling the inflate method:

layoutInflater.inflate(resource, root, true);  

The inflate method in LayoutInflater has several overload methods, and the following code is finally called:

1 public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot) {2 synchronized (mConstructorArgs) {3 // get attribute information in xml 4 final AttributeSet attrs = Xml. asAttributeSet (parser); 5 Context lastContext = (Context) mConstructorArgs [0]; 6 mConstructorArgs [0] = mContext; 7 View result = root; 8 9 try {10 // find the root node. 11 int type; 12 while (type = parser. next ())! = XmlPullParser. START_TAG & 13 type! = XmlPullParser. END_DOCUMENT) {14 // Empty 15} 16 17 if (type! = XmlPullParser. START_TAG) {18 throw new InflateException (parser. getPositionDescription () 19 + ": No start tag found! "); 20} 21 // get the root node name 22 final String name = parser. getName (); 23 24 if (DEBUG) {25 System. out. println ("*************************"); 26 System. out. println ("Creating root view:" 27 + name); 28 System. out. println ("**************************"); 29} 30 // For the merge tag, ensure that the parent node is not null and the attachToRoot is true 31 if (TAG_MERGE.equals (name) {32 if (root = null |! AttachToRoot) {33 throw new InflateException ("<merge/> can be used only with a valid" 34 + "ViewGroup root and attachToRoot = true "); 35} 36 37 rInflate (parser, root, attrs, false); 38} else {39 // view 40 View temp of the root node in the layout file; 41 if (TAG_1995.equals (name) {42 temp = new BlinkLayout (mContext, attrs); 43} else {44 // use reflection, create view 45 temp = createViewFromTag (root, name, attrs) with the root name; 46} 47 4 8 ViewGroup. LayoutParams params = null; 49 50 if (root! = Null) {51 if (DEBUG) {52 System. out. println ("Creating params from root:" + 53 root); 54} 55 // Create layout params that match root, if supplied 56 // when a parent container is provided, the layout parameter 57 params = root is created by the parent container based on the property value. generateLayoutParams (attrs); 58 if (! AttachToRoot) {59 // Set the layout params for temp if we are not 60 // attaching. (If we are, we use addView, below) 61 // when the current view is not appended to the parent container, then set the obtained layout parameter 62 // otherwise, use the addView method below to set 63 temp. setLayoutParams (params); 64} 65} 66 67 if (DEBUG) {68 System. out. println ("-----> start inflating children"); 69} 70 // Inflate all children under temp 71 // recursively call this method to load the sub-layout 72 rInflate (parser, temp, attrs, true); 73 If (DEBUG) {74 System. out. println ("-----> done inflating children"); 75} 76 77 // We are supposed to attach all the views we found (int temp) 78 // to root. do that now. 79 if (root! = Null & attachToRoot) {80 root. addView (temp, params); 81} 82 83 // Decide whether to return the root that was passed in or the 84 // top view found in xml. 85 if (root = null |! AttachToRoot) {86 result = temp; 87} 88} 89 90} catch (XmlPullParserException e) {91 InflateException ex = new InflateException (e. getMessage (); 92 ex. initCause (e); 93 throw ex; 94} catch (IOException e) {95 InflateException ex = new InflateException (96 parser. getPositionDescription () 97 + ":" + e. getMessage (); 98 ex. initCause (e); 99 throw ex; 100} finally {101 // Don't retain static reference on context.102 mConstructorArgs [0] = lastContext; 103 mConstructorArgs [1] = null; 104} 105 106 return result; 107} 108}

Here, Android uses PULL to parse the xml layout file and use reflection to create the current view:

temp = createViewFromTag(root, name, attrs);

 

Let's take a look at the source code:

 1 View createViewFromTag(View parent, String name, AttributeSet attrs) { 2         if (name.equals("view")) { 3             name = attrs.getAttributeValue(null, "class"); 4         } 5  6         if (DEBUG) System.out.println("******** Creating view: " + name); 7  8         try { 9             View view;10             if (mFactory2 != null) view = mFactory2.onCreateView(parent, name, mContext, attrs);11             else if (mFactory != null) view = mFactory.onCreateView(name, mContext, attrs);12             else view = null;13 14             if (view == null && mPrivateFactory != null) {15                 view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);16             }17             18             if (view == null) {19                 if (-1 == name.indexOf('.')) {20                     view = onCreateView(parent, name, attrs);21                 } else {22                     view = createView(name, null, attrs);23                 }24             }25 26             if (DEBUG) System.out.println("Created view is: " + view);27             return view;28 29         } catch (InflateException e) {30             throw e;31 32         } catch (ClassNotFoundException e) {33             InflateException ie = new InflateException(attrs.getPositionDescription()34                     + ": Error inflating class " + name);35             ie.initCause(e);36             throw ie;37 38         } catch (Exception e) {39             InflateException ie = new InflateException(attrs.getPositionDescription()40                     + ": Error inflating class " + name);41             ie.initCause(e);42             throw ie;43         }44     }

The onCreateView method is called based on different situations, and the view is created by reflection. You can use the specified factory to create a view. This hook design makes the inflate method very flexible.

Then, call the rInflate (parser, temp, attrs, true) method to recursively find the child view in temp and add it to the upper view:

 1 void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs, 2             boolean finishInflate) throws XmlPullParserException, IOException { 3  4         final int depth = parser.getDepth(); 5         int type; 6  7         while (((type = parser.next()) != XmlPullParser.END_TAG || 8                 parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { 9 10             if (type != XmlPullParser.START_TAG) {11                 continue;12             }13 14             final String name = parser.getName();15             16             if (TAG_REQUEST_FOCUS.equals(name)) {17                 parseRequestFocus(parser, parent);18             } else if (TAG_INCLUDE.equals(name)) {19                 if (parser.getDepth() == 0) {20                     throw new InflateException("<include /> cannot be the root element");21                 }22                 parseInclude(parser, parent, attrs);23             } else if (TAG_MERGE.equals(name)) {24                 throw new InflateException("<merge /> must be the root element");25             } else if (TAG_1995.equals(name)) {26                 final View view = new BlinkLayout(mContext, attrs);27                 final ViewGroup viewGroup = (ViewGroup) parent;28                 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);29                 rInflate(parser, view, attrs, true);30                 viewGroup.addView(view, params);                31             } else {32                 final View view = createViewFromTag(parent, name, attrs);33                 final ViewGroup viewGroup = (ViewGroup) parent;34                 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);35                 rInflate(parser, view, attrs, true);36                 viewGroup.addView(view, params);37             }38         }39 40         if (finishInflate) parent.onFinishInflate();41     }

The onCreateView method is also used to create a sub-view, and then add it to the parent view to return.

By viewing the source code above, we can find that the three parameters int resource, ViewGroup root, and boolean attachToRoot in the inflate method have the following functions:

Resource specifies the view to be loaded. root serves as the parent container of the Outside view layer. attachToRoot indicates whether to add the view to the parent container.

If the parent container is specified and the value of attachToRoot is true, the view is added to the parent container.

If the parent container is specified but the value of attachToRoot is set to false, the view layout parameters are generated from the parent container and set to view.

If no parent container is specified, view itself is directly returned.

 

Summary

By studying the LayoutInflater source code design, we can also find that:

LayoutInflater uses the simple factory mode when creating a view object, and adds the Hook method to abstract the factory mode so that coder can create a view using a custom factory method.

 

Related Article

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.