LayoutInflater。膨胀文档对我来说并不完全清楚attachtorroot参数的用途。
attachtorroot:膨胀的层次结构是否应该附加到根参数?如果为false,则root仅用于创建正确的 XML中根视图的LayoutParams的子类。
有没有人能更详细地解释一下,具体地说,根视图是什么,也许还能举个例子,说明在真值和假值之间的行为变化?
LayoutInflater。膨胀文档对我来说并不完全清楚attachtorroot参数的用途。
attachtorroot:膨胀的层次结构是否应该附加到根参数?如果为false,则root仅用于创建正确的 XML中根视图的LayoutParams的子类。
有没有人能更详细地解释一下,具体地说,根视图是什么,也许还能举个例子,说明在真值和假值之间的行为变化?
当前回答
当你定义父对象时,attachtorroot决定你是否想要膨胀器把它附加到父对象上。在某些情况下,这会导致问题,比如在ListAdapter中,它会导致一个异常,因为列表试图将视图添加到列表中,但它说它已经附加。在其他情况下,您只是自己膨胀视图以添加到活动,这可能很方便,并节省了一行代码。
其他回答
由于inflation()方法的文档,关于这个主题有很多困惑。
通常,如果attachtorroot被设置为true,那么第一个参数中指定的布局文件将被膨胀,并在那个时刻附加到第二个参数中指定的ViewGroup。当attachtorroot为false时,来自第一个参数的布局文件将膨胀并作为视图返回,任何视图附件都在其他时间发生。
This probably doesn't mean much unless you see a lot of examples. When calling LayoutInflater.inflate() inside of the onCreateView method of a Fragment, you will want to pass in false for attachToRoot because the Activity associated with that Fragment is actually responsible for adding that Fragment's view. If you are manually inflating and adding a View to another View at some later point in time, such as with the addView() method, you will want to pass in false for attachToRoot because the attachment comes at a later point in time.
您可以在我写的一篇关于这个主题的博客文章中阅读其他几个关于对话框和自定义视图的独特示例。
https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/
attachtorroot设置为true意味着inflatedView将被添加到父视图的层次结构中。因此,用户可能会“看到”并感知触摸事件(或任何其他UI操作)。否则,它只是被创建了,没有被添加到任何视图层次结构中,因此不能被看到或处理触摸事件。
对于刚接触Android的iOS开发者,attachtorroot设置为true意味着你调用这个方法:
[parent addSubview:inflatedView];
如果更进一步,你可能会问:如果我将attachtorroot设置为false,为什么我要传递父视图?这是因为XML树中的根元素需要父视图来计算一些LayoutParams(比如match parent)。
现在与否
“第三个”参数attachtorroot是真还是假的主要区别是这样的。
当你输入attachtorroot
true:立即将子视图添加到父视图 false:现在将子视图添加到父视图。 稍后再添加。`
什么时候?
后面就是使用parent。addview (childView)
一个常见的误解是,如果attachtorroot参数为false,那么子视图将不会被添加到父视图。错误的 在这两种情况下,子视图将被添加到parentView。这只是时间问题。
inflater.inflate(child,parent,false);
parent.addView(child);
等于
inflater.inflate(child,parent,true);
一个大禁忌 当您不负责将子视图添加到父视图时,永远不要将attachtorroot传递为true。 当添加片段时
public View onCreateView(LayoutInflater inflater,ViewGroup parent,Bundle bundle)
{
super.onCreateView(inflater,parent,bundle);
View view = inflater.inflate(R.layout.image_fragment,parent,false);
.....
return view;
}
如果你传递第三个参数为true,你会得到IllegalStateException,因为这个家伙。
getSupportFragmentManager()
.beginTransaction()
.add(parent, childFragment)
.commit();
因为你已经在onCreateView()中错误地添加了子片段,调用add会告诉你子视图已经添加到父视图,因此IllegalStateException。 这里你不负责添加childView, FragmentManager负责。这里总是传递false。
注意:我还读到,如果attachtorroot为false, parentView将不会获得childView touchEvents。但我还没有测试过。
回复中似乎有很多文本,但没有代码,这就是为什么我决定用一个代码示例来恢复这个老问题,在几个回复中人们提到:
如果设置为true,那么当你的布局膨胀时,它将自动添加到ViewGroup的视图层次结构中,在第二个参数中指定作为子参数。
这在代码中的实际含义(大多数程序员都能理解)是:
public class MyCustomLayout extends LinearLayout {
public MyCustomLayout(Context context) {
super(context);
// Inflate the view from the layout resource and pass it as child of mine (Notice I'm a LinearLayout class).
LayoutInflater.from(context).inflate(R.layout.child_view, this, true);
}
}
注意,前面的代码添加了布局R.layout。child_view作为MyCustomLayout的孩子,因为attachToRoot参数为真,并以完全相同的方式分配父布局参数,如果我将使用addView编程,或如果我在xml中这样做:
LinearLayout < > <视图…/ > ... LinearLayout < / >
下面的代码解释了当传递attachRoot为false时的场景:
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
// Create a stand-alone view
View myView = LayoutInflater.from(context)
.inflate(R.layout.ownRootView, null, false);
linearLayout.addView(myView);
在前面的代码中,你指定你想要myView是它自己的根对象,不附加到任何父对象,后来我们将它添加为LinearLayout的一部分,但暂时它是一个独立的(没有父)视图。
同样的事情也发生在Fragments上,你可以将它们添加到一个已经存在的组中并成为它的一部分,或者只是传递参数:
inflater. inflation (r.b ayout.fragment, null, false);
来指定它将是它自己的根。
当你定义父对象时,attachtorroot决定你是否想要膨胀器把它附加到父对象上。在某些情况下,这会导致问题,比如在ListAdapter中,它会导致一个异常,因为列表试图将视图添加到列表中,但它说它已经附加。在其他情况下,您只是自己膨胀视图以添加到活动,这可能很方便,并节省了一行代码。