java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

时间:2022-02-26 20:34:10

使用RecyclerView时候,突然出现这个异常,真是百思不得其解。

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

这个问题翻译过来就是非法状态异常它说这个特定的child已经有一个parent了,你必须在这个parent中首先调用removeView()方法,才能继续你的内容。这里很明显这个child是一个View,一个子(childView必须依赖于父(parentView,如果你要使用这个child,则必须通过parent,而你如果就是硬想使用这个child,那么就得让这个childparent脱离父子关系(即removeView())。

然后我把RecyclerView初始化那部分注掉,程序正常运行。打开以后程序就崩溃了,然后只把findViewById和设置适配的部分打开也正常,当我又把

mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
这一行打开后程序就出刚才的问题了。看来这是展示RecyclerView的关键代码,然后我把这一行注掉其他初始化部分全打开,程序正常运行,没有奔溃就是RecyclerView没有在界面上出现。我这时发现
E/RecyclerView: No layout manager attached; skipping layout
这一行信息。看来还是布局的问题。。。可是究竟怎么回事啊?难道我的适配器有问题吗。。。

最后试了好多次,我发现我在布局填充的时候(也就是使用布局填充器给RecyclerView设置itemView的时候)使用的是

LayoutInflater.from(mContext).inflate(R.layout.item_layout_parper,parent);
因为其他地方都检查过了没问题,所以感觉是不是这的问题,我发现这里面好像在往常看代码时候是三个参数的,最后我加了一个false参数,所有问题解决了。
LayoutInflater.from(mContext).inflate(R.layout.item_layout_parper,parent,false);

点进去inflate()方法中看到源码是这样解释这个false参数的:

* @param attachToRoot Whether the inflated hierarchy should be attached to * the root parameter? If false, root is only used to create the * correct subclass of LayoutParams for the root view in the XML.
就是说如果不设置为false,这个itemView就是默认依附在rootView即activity的布局上的,但其实它是直接依附在recyclerView上的。因此相当于中间略去了它的直接parent,想要从他的祖父那拿到布局,绝对是不可以的。因此提示非法状态异常,建议咱们先切断它和recyclerView之间的联系,然后直接和它祖父建立关系。。。那样绝对不行啊,已经乱伦了,因此我们还是乖乖的修改代码,给child找到他的parent,这样说你应该理解吧!总之问题层出不穷,梳理清楚之后就会觉得这不算是bug,只是我们知识不全面而已!