我通常不回答自己的问题,但是在为此做更多研究后,我认为这可能会帮助其他人。尽管Marcin的答案是正确的,但我将详细回答一下。
根据代码:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.example_fragment, container, false);
}
第二个参数container是一个帧布局,具有id fragment_container,该活动使用它将片段添加到其布局中。
现在,如果我们深入了解LayoutInflater类的inflate方法,这是代码(我只突出显示相关代码而不是整个代码):
View result = root;
final View temp = createViewFromTag(root, name, attrs, false);
首先,它从提供的根创建一个临时视图。
如果
attachToRoot 是 true,那么它会这样做:
if (root != null && attachToRoot) {
root.addView(temp, params);
}
它将上面创建的临时视图添加到根视图(即容器)中。
如果attachToRoot为false,则会执行以下操作:
if (root == null || !attachToRoot) {
result = temp;
}
显而易见,如果 attachToRoot 为 true,则它只需将临时视图添加到根视图(在此示例中为 example_fragment 中的 Root view),然后返回根视图(即 fragment_container,即活动用于放置片段的 id)。如果 attachToRoot 为 false,则它只返回片段 xml 的根视图,即容器参数仅用于获取片段根视图的布局参数(因为它没有根视图,所以需要从其他地方获取参数)。
当 attachToRoot 为 true 时,上面的示例存在问题,因为返回值是带有已添加视图 temp 的根视图(fragment_container 默认已经有一个父级)。现在,如果您尝试进行片段事务,则正在尝试将子视图 fragment_container(已经有父级)添加到另一个 xml(您定义的 framelayout 以添加片段)中。
由于这个原因,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专家纠正。