关于inflater.inflate Android文档的困惑

时间:2015-08-06 11:29:19

标签: 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);
}

}

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

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

  

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

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

5 个答案:

答案 0 :(得分: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);
}

第二个参数容器是一个带有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);

首先,它从提供的根创建一个临时视图。

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

if (root != null && attachToRoot) {
    root.addView(temp, params);
}

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

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

if (root == null || !attachToRoot) {
   result = temp;   
}

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

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

上述示例中出现了true的问题,因为返回值是root(fragment_container添加了视图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专家来纠正这个问题。

答案 1 :(得分:4)

这意味着,如果onCreateView()返回View,则会将其附加到容器视图中,因此将其设置为true中的onCreateView()会导致其被添加两次到容器布局,这不是你通常想要的。并且将根视图设置为not null并且仍然有attachToRoot false允许膨胀视图从root派生,不添加。

答案 2 :(得分:1)

检查这个

View v =getLayoutInflater.inflate(R.layout.example_fragment, viewgroup);

还有这个

View v =getLayoutInflater.inflate(R.layout.example_fragment, null);

现在如果你为第一个场景调用它

Log.v("testing",String.valueOf(v.getParent() == null));

您将获得false作为输出,但当您在第二行检查时,您将获得true

简单的理解是,如果您指定它附加到它的父(ViewGroup),但是如果添加最后一个参数,则告诉inflater跳过View的附件,以便返回的View没有父级,但是如果你指定null,谁将被附加? NOBODY所以返回的View没有父级,也像你声明的那样派生了View的layoutParameters。

如果你不添加最后一个参数,View将把它的父项作为Activity View,因此在你的OncreateView中已经有父项之前会返回它,然后才会添加它,这会导致一些异常作为View不能有不同的daddies,Fragment将无法管理View本身。

如果从oncreateView

添加true返回null

答案 3 :(得分:-2)

从片段的onCreateView()方法返回的视图将由系统附加到片段的容器中。因此,在这种情况下,inflate()方法的第三个参数应为false。如果将其设置为true,则它将连接到根两次。所以在这种情况下你应该把它设置为假。

现在,膨胀的视图从inflate()方法的第二个参数派生其布局参数,而不是从第三个布尔参数派生。

答案 4 :(得分:-2)

好的,来自android官方文档Android documentation

  

什么是片段?

Fragment表示Activity中的行为或用户界面的一部分。您可以在单个活动中组合多个片段以构建多窗格UI,并在多个活动中重用片段。您可以将片段视为活动的模块化部分,它具有自己的生命周期,接收自己的输入事件,并且可以在活动运行时添加或删除(有点像“子活动”,您可以在不同的活动中重复使用)。

  

如何在活动中使用片段?

片段必须始终嵌入到活动中,片段的生命周期直接受主机活动生命周期的影响。例如,当活动暂停时,其中的所有片段也都会暂停,当活动被破坏时,所有片段也都会被破坏。但是,当一个活动正在运行时(它处于恢复的生命周期状态),您可以单独操作每个碎片,例如添加或删除它们。

  

什么是片段交易

您可以单独操作每个片段,例如添加或删除它们。执行此类片段事务时,还可以将其添加到由活动管理的后台堆栈中 - 活动中的每个后台堆栈条目都是发生的片段事务的记录。后向堆栈允许用户通过按“返回”按钮来反转片段事务(向后导航)。

  

碎片和活动如何相互作用

当您将片段添加为活动布局的一部分时,它将位于活动视图层次结构内的ViewGroup中,并且片段定义自己的视图布局。您可以通过将活动的布局文件中的片段声明为元素,或者通过将其添加到现有ViewGroup,从应用程序代码中将片段插入到活动布局中。

  

片段生命周期方法onCreateView()      的onCreate()      的onPause()

你的问题是

  

我们已经插入容器而没有attachToRoot是真的意味着什么?如果参数为true,那么最终布局将如何具有冗余视图组

这里是回答 假设您已经在活动布局中添加了,那么您不需要将最后一个参数设置为true。因为每次执行添加或删除片段时,它们都是片段事务。 但是,如果您尚未在布局中添加片段,则可以将其设置为true。

在doc

中阅读
  

您可以通过将活动布局文件中的片段作为元素声明,或者通过将其添加到现有ViewGroup中,从应用程序代码中将片段插入活动布局。但是,片段不需要是活动布局的一部分;您也可以使用没有自己的UI的片段作为活动的隐形工作者。

所有片段事务都添加在活动后台堆栈