我通常不会回答自己的问题,但在为此做了更多研究之后,我想也许这会对其他人有所帮助。虽然Marcin的答案是正确的,但我只是回答得更详细一点。
根据代码:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
第二个参数容器是一个 ID 为fragment_container 的框架布局,活动使用它来将片段添加到其布局中。
现在,如果我们深入研究 LayoutInflater 类的 inflate 方法,这就是代码(我只是突出显示代码的相关部分而不是整个部分):
// The view that would be returned from this method.
View result = root;
// Temp is the root view that was found in the xml.
final View temp = createViewFromTag(root, name, attrs, false);
首先,它从提供的根创建一个临时视图。
In case AttachToRoot 为 true,它这样做:
if (root != null && attachToRoot) {
root.addView(temp, params);
}
它将上面创建的临时视图添加到根视图(即容器)。
In case 附加到根目录为 false,它执行以下操作:
if (root == null || !attachToRoot) {
result = temp;
}
很明显,如果AttachToRoot 为 true,它只是在向其添加临时视图后返回根(fragment_container,即 id 活动用于将片段放入其中。)(在本例中为 example_fragment 中的根视图))。
In case AttachToRoot 为 false,它只是返回片段 xml 的根,即容器参数仅用于获取片段根视图的布局参数(因为它没有根,所以它需要从某个地方获取参数)。
如果为 true,则问题出现在上面的示例中,因为返回值是 root(fragment_container 添加了视图温度,而fragment_container 默认情况下已经有一个父级。)。现在,如果您尝试执行片段事务,则您正在尝试添加子视图fragment_container(已经有一个父母到另一个 xml(您定义的用于添加片段的框架布局)。
因此,Android 会抛出以下异常:
if (child.getParent() != null) {
throw new IllegalStateException("The specified child already has a parent. " +
"You must call removeView() on the child's parent first.");
}
将其设置为 true 并返回时的问题是返回的视图已经有父级,因此不能在其他地方使用。其他方式,您可以在 onCreateView (可能是 LinearLayout)内创建一个单独的视图组,将参数设置为 true,然后返回视图。然后它就会正常工作,因为视图组没有现有的父级。
这是我对上述问题的理解,我可能是错的,在这种情况下我希望任何Android专家纠正这个问题。