本文共 4871 字,大约阅读时间需要 16 分钟。
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child’s parent first.
这个问题的原因很简单,该异常表示已经存在父布局,不能再添加父布局。导致该异常的代码可能是:
View view = LayoutInflater.from(getContext()).inflate(R.layout.news_item, parent);
在 inflate() 方法上加入第三个参数,指定为 false 即可。
通常情况下,我们在获取View的时候一般代码都是:
View view = LayoutInflater.from(getContext()).inflate(R.layout.news_item, parent,false);
注意第三个参数为false,所以在获取View的时候并不会把parent设置为View的父布局。默认情况下,如果你不设置inflate的第三个参数,这个参数默认为parent!=null的值。
源码如下:public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); } 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("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 xml 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); } // Create layout params that match root, if supplied params = 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) { final InflateException ie = new InflateException(e.getMessage(), e); ie.setStackTrace(EMPTY_STACK_TRACE); throw ie; } catch (Exception e) { final InflateException ie = new InflateException(parser.getPositionDescription() + ": " + e.getMessage(), e); ie.setStackTrace(EMPTY_STACK_TRACE); throw ie; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; Trace.traceEnd(Trace.TRACE_TAG_VIEW); } return result; } }
相信读完源码,大家 就会对这个异常晃人大悟了。
转载地址:http://ygcqf.baihongyu.com/