我得到了这段代码:
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater!!.inflate(R.layout.fragment_wednesday, container, false)
}
我不明白为什么我们需要对布局进行膨胀并写入attachToRoot值。 顺便说一下,为什么我们需要一个viewGroup?
答案 0 :(得分:1)
布局定义只是一些XML数据,但要真正显示布局,必须将其转换为对象树。 inflater就是这样做的。
需要一个容器(ILayoutContainer
)来控制放置子树的位置(在较大的视图对象树中)。
答案 1 :(得分:0)
考虑这段代码
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup fragment_container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, fragment_container, false);
}
第二个参数fragment_container是一个容器(framelayout),其id为fragment_container,activity用于在其布局中添加片段视图。
没有,如果我们读取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为false,则执行以下操作:
// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}
如果attachToRoot为false,它只返回片段的xml的根,即容器参数仅用于获取片段根视图的layoutParams(因为它没有root,所以它需要来自某处的params)
如果attachToRoot为true,则执行以下操作:
// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
root.addView(temp, params);
}
它将上面创建的临时视图添加到根视图(即容器)。
“第三”参数attachToRoot为true或false的主要区别在于。
true :将子视图添加到父级RIGHT
false :将子视图添加到父级NOT NOW。稍后再添加。 `
以后是什么时候?
稍后您使用例如parent.addView(childView)
一个常见的误解是,如果attachToRoot参数为false,则子视图不会添加到父视图中。的 WRONG 强> 在这两种情况下,子视图都将添加到parentView。这只是时间的问题。
inflater.inflate(child,parent,false);
parent.addView(child);
相当于
inflater.inflate(child,parent,true);
注意!!注意 !!注意!!
如果您不负责将子视图添加到父级,则不应将attachToRoot传递为true。
例如,添加片段时
public View onCreateView(LayoutInflater inflater,ViewGroup parent,Bundle bundle)
{
super.onCreateView(inflater,parent,bundle);
View v = inflater.inflate(R.layout.image_fragment,parent,false);
return v;
}
现在,如果您将第三个参数传递为true,则会因为以下代码而获得IllegalStateException。
getSupportFragmentManager()
.beginTransaction()
.add(parent, childFragment)
.commit();
由于您已经错误地在onCreateView()中添加了子片段。调用add将告诉您子视图已添加到父级,因此IllegalStateException。此异常来自以下代码,可在检查LayoutInflater类中的inflate方法时找到该代码
if (child.getParent() != null) {
throw new IllegalStateException("The specified child already has a parent. " +
"You must call removeView() on the child's parent first.");
}
这里你不负责添加childView,FragmentManager负责。所以在这种情况下总是传递假的