问题描述
在安卓里面加载一个layout布局,我们通常会用到LayoutInflater.from(context).inflate()方法。但是在将这些加载出来的View添加到现有的ViewGroup中的时候,可能会报以下异常:
java.lang.IllegalStateException The specified child already has a parent. You must call removeView() on the child's parent first.
可能的原因
LayoutInflater的inflate方法包含三个参数:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
final XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
resource表示需要加载的资源,root就是加载布局的parent,主要作用是为需要加载的布局资源提供一系列适当类型的LayoutParams参数,当第三个参数attachToRoot为true的时候,加载的布局会添加到root的布局结构里面,否则root的作用就只是提供适当类型的LayoutParams参数。虽然root可以为空,但是并不建议如此。
My Solution
1、将attachToRoot参数设为false
如果使用的是LayoutInflater的inflate方法,需要将
View view = inflater.inflate(R.layout.child_layout, parent);
改成
View view = inflater.inflate(R.layout.child_layout, parent, false);
2、在添加view之前获取parent,并手动删除view。
如果不是使用LayoutInflater的inflate方法,可以在添加子View之前,手动删除该View。
if (view.getParent() != null) {
((ViewGroup)view.getParent()).removeView(view);
}
参考资料
关于异常“The specified child already has a parent. You must call removeView"的解决(举例说明,附源码)
stackoverflow 问题1
stackoverflow 问题2
stackoverflow 问题3
网友评论