关于inflater.inflate Android文档的困惑

gau*_*ain 3 android android-fragments

我正在研究这个链接的片段:http://developer.android.com/guide/components/fragments.html

有一段代码给出:

public static class ExampleFragment extends Fragment {
@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);
}
Run Code Online (Sandbox Code Playgroud)

}

我对attachToRoot参数感到困惑,所以我查看了Stack Overflow的一些帮助,并找到了类似问题的好答案.所以我理解的是,如果将其设置为true,则片段将附加到活动的根布局,并从那里派生其布局框架.如果它是假的,它将简单地返回膨胀布局的根,并且像片段的独立视图(从传入的容器中导出布局参数).

现在我在上面的例子中关于attachToRoot的文档中进一步阅读:

一个布尔值,指示在充气期间是否应将膨胀的布局附加到ViewGroup(第二个参数).(在这种情况下,这是错误的,因为系统已经将膨胀的布局插入到容器中 - 传递true会在最终布局中创建冗余视图组.)

我没有得到最后一个括号语句,它说它应该是假的,因为我们已经将布局插入到容器中.在没有attachToRoot为真的情况下,我们已经插入容器是什么意思?如果参数为true,则最终布局如何具有冗余视图组.详细说明这一部分的一个例子将是一个很大的帮助.谢谢.

gau*_*ain 5

我通常不回答我自己的问题,但在对此进行了一些研究之后,我想也许这会对其他人有所帮助.尽管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);
}
Run Code Online (Sandbox Code Playgroud)

第二个参数容器是一个带有id fragment_container的framelayout,活动用它来将片段添加到它的布局中.

现在,如果我们深入研究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);
Run Code Online (Sandbox Code Playgroud)

首先,它从提供的根创建临时视图.

如果attachToRoot为true,则执行以下操作:

if (root != null && attachToRoot) {
    root.addView(temp, params);
}
Run Code Online (Sandbox Code Playgroud)

它将上面创建的临时视图添加到根视图(即容器).

如果attachToRoot为false,则执行以下操作:

if (root == null || !attachToRoot) {
   result = temp;   
}
Run Code Online (Sandbox Code Playgroud)

很明显,如果attachToRoot为true,它只是返回根(fragment_container,即id活动用于将片段放入其中.)在向其添加临时视图后(在本例中为example_fragment中的根视图)).

如果attachToRoot为false,它只返回片段的xml的根,即容器参数仅用于获取片段根视图的layoutParams(因为它没有root,所以它需要来自某处的params).

在上面的示例中出现了true的问题,因为返回值是root(具有添加的视图临时的fragment_container,默认情况下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.");
    }
Run Code Online (Sandbox Code Playgroud)

将其设置为true并返回时出现的问题是返回的视图已经具有父级,因此不能在其他地方使用.换句话说,您可以在onCreateView(可能是LinearLayout)中创建一个单独的视图组,将参数设置为true,然后返回视图.然后它将正常工作,因为视图组将没有现有的父级.

这是我对上述问题的理解,我可能错了,在这种情况下我想要任何Android专家来纠正这个问题.