Android LayoutInflater.inflate源码解析
一年多以前看過源碼,感覺了解比較透徹了,長時間不經大腦思考,靠曾經總結的經驗使用inflate方法,突然發現不知道什么時候忘記其中的原理了,上網查了一些資料,還各有不同,反而把我搞糊涂了,還是自己看源碼來的實在。
inflate有多個重載方法,不過殊途同歸,最后的歸宿都是下面這個家伙:
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 {// Look for the root node.int type;while ((type = parser.next()) != XmlPullParser.START_TAG &&type != XmlPullParser.END_DOCUMENT) {// Empty }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 {// Temp is the root view that was found in the xmlfinal View temp = createViewFromTag(root, name, inflaterContext, attrs);ViewGroup.LayoutParams params = null;if (root != null) {if (DEBUG) {System.out.println("Creating params from root: " +root);}// Create layout params that match root, if suppliedparams = root.generateLayoutParams(attrs);if (!attachToRoot) {// Set the layout params for temp if we are not// attaching. (If we are, we use addView, below) temp.setLayoutParams(params);}}if (DEBUG) {System.out.println("-----> start inflating children");}// Inflate all children under temp against its context.rInflateChildren(parser, temp, attrs, true);if (DEBUG) {System.out.println("-----> done inflating children");}// We are supposed to attach all the views we found (int temp)// to root. Do that now.if (root != null && attachToRoot) {root.addView(temp, params);}// Decide whether to return the root that was passed in or the// top view found in xml.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 {// Don't retain static reference on context.mConstructorArgs[0] = lastContext;mConstructorArgs[1] = null;}Trace.traceEnd(Trace.TRACE_TAG_VIEW);return result;}}1.首先來看看 root!=null && attachToRoot==true的情況:
if (root != null && attachToRoot) {root.addView(temp, params);}直接將layout添加至root中,此方法相當于將layout的代碼直接放置在root布局的根布局下。
此方法的返回值為root。
2.再看看root!=null && attachToRoot==false的情況:
if (root != null) {params = root.generateLayoutParams(attrs);if (!attachToRoot) {temp.setLayoutParams(params);}}此方法返回的值為layout,且layout中設置了自己的layoutParams。
3.最后就是root==null的情況了:
此方法返回的也是layout,與第二種情況不同的是layout中不含layoutParams。
?
注:與第1中情況不同,第2和第3種情況需自己調用addview方法添加至相應布局中。
?
總結:
1.?root!=null && attachToRoot==true ?-----> ?將layout完全地添加到root中,返回root。
2.?root!=null && attachToRoot==false------> ?返回的layout(包含layoutParams)
3.?root==nul -------------------------------> ?返回layout(不包含layoutParams)
?
轉載于:https://www.cnblogs.com/zhisuoyu/p/5924396.html
總結
以上是生活随笔為你收集整理的Android LayoutInflater.inflate源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从头开始 启动开源电商项目jShop
- 下一篇: Tomcat启动过程源码分析六