LayoutInflater源码分析
与setContentView相关
在PhoneWindow的generateLayout中调用了 1 View in = mLayoutInflater.inflate(layoutResource, null );
LayoutInflater中获取实例化方法
1 2 3 4 5 6 7 8 9 10 11 public static LayoutInflater from (Context context) { LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (LayoutInflater == null ) { throw new AssertionError ("LayoutInflater not found." ); } return LayoutInflater; }
inflate方法相关
1 2 3 4 5 6 7 public View inflate (@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null ); } public View inflate (XmlPullParser parser, @Nullable ViewGroup root) { return inflate(parser, root, root != null ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public View inflate (@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) { final Resources res = getContext().getResources(); if (DEBUG) { Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" (" + Integer.toHexString(resource) + ")" ); } final XmlResourceParser parser = res.getLayout(resource); try { return inflate(parser, root, attachToRoot); } finally { parser.close(); } }
最后发现都需要调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 public View inflate (XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate" ); final Context inflaterContext = mContext; final AttributeSet attrs = Xml.asAttributeSet(parser); Context lastContext = (Context) mConstructorArgs[0 ]; mConstructorArgs[0 ] = inflaterContext; View result = root; try { int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { } if (type != XmlPullParser.START_TAG) { throw new InflateException (parser.getPositionDescription() + ": No start tag found!" ); } final String name = parser.getName(); if (DEBUG) { System.out.println("**************************" ); System.out.println("Creating root view: " + name); System.out.println("**************************" ); } if (TAG_MERGE.equals(name)) { if (root == null || !attachToRoot) { throw new InflateException ("<merge /> can be used only with a valid " + "ViewGroup root and attachToRoot=true" ); } rInflate(parser, root, inflaterContext, attrs, false ); } else { final View temp = createViewFromTag(root, name, inflaterContext, attrs); ViewGroup.LayoutParams params = null ; if (root != null ) { if (DEBUG) { System.out.println("Creating params from root: " + root); } params = root.generateLayoutParams(attrs); if (!attachToRoot) { temp.setLayoutParams(params); } } if (DEBUG) { System.out.println("-----> start inflating children" ); } rInflateChildren(parser, temp, attrs, true ); if (DEBUG) { System.out.println("-----> done inflating children" ); } if (root != null && attachToRoot) { root.addView(temp, params); } if (root == null || !attachToRoot) { result = temp; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException (e.getMessage()); ex.initCause(e); throw ex; } catch (Exception e) { InflateException ex = new InflateException ( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } finally { mConstructorArgs[0 ] = lastContext; mConstructorArgs[1 ] = null ; } Trace.traceEnd(Trace.TRACE_TAG_VIEW); return result; } }
相关inflate参数的结果
相关方法解析 在Inflate中多次被调用的rInflate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 void rInflate (XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue ; } final String name = parser.getName(); if (TAG_REQUEST_FOCUS.equals(name)) { parseRequestFocus(parser, parent); } else if (TAG_TAG.equals(name)) { parseViewTag(parser, parent, attrs); } else if (TAG_INCLUDE.equals(name)) { if (parser.getDepth() == 0 ) { throw new InflateException ("<include /> cannot be the root element" ); } parseInclude(parser, context, parent, attrs); } else if (TAG_MERGE.equals(name)) { throw new InflateException ("<merge /> must be the root element" ); } else { final View view = createViewFromTag(parent, name, context, attrs); final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflateChildren(parser, view, attrs, true ); viewGroup.addView(view, params); } } if (finishInflate) { parent.onFinishInflate(); } } protected void onFinishInflate () { }