android Fragment java.lang.IllegalStateException:The specified child already has a parent.

在做项目的时候 ,做到了一个Activity里面有两个Tab切换,每一个Tab是一个Fragment展示内容,当两个Tab来回切换的时候,报了一个错误

android Fragment java.lang.IllegalStateException:The specified child already has a parent._第1张图片


经过查找原因,原来是Fragment中OnCreateView()的方法调用错了:


正确的方法应该是:

查阅多方资料得知,我们都LayoutInflater的使用存在误区

我们最常用的便是 LayoutInflater的inflate方法,这个方法重载了四种调用方式,分别为:

1. public View inflate(int resource, ViewGroup root)

2.  public View inflate(int resource, ViewGroup root, boolean attachToRoot)

3.public View inflate(XmlPullParser parser, ViewGroup root)

4.public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)


这四种使用方式中,我们最常用的是第一种方式, inflate方法的主要作用就是将xml转换成一个View对象,用于动态的创建布局。虽然重载了四个方法,但是这四种方法最终调用的,还是第四种方式。第四种方式也很好理解,内部实现原理就是利用Pull解析器,对Xml文件进行解析,然后返回View对象。

inflate方法有三个参数,分别是

1. resource 布局的资源id

2. root 填充的根视图

3.attachToRoot是否将载入的视图绑定到根视图中

一般情况下,我们将BaseAdapter中的getView()方法:中根视图设置为null,

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = inflate(R.layout.item_row, null);
    }
    return convertView;
}
和我们将根视图设置为false

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

      if (convertView == null) {
        convertView = inflater.inflate(R.layout.item_list, parent,false);
      }
      return convertView;
    }
的区别是,如果在listview中的Item中根布局设置高度为40dp的话,第一种就没有效果。

经过看源码分析,当我们传进来的root参数不是空的时候,并且attachToRoot是false的时候,会重新给设置参数。

若我们采用 convertView = inflater.inflate(R.layout.item_list, null);方式填充视图,item布局中的根视图的layout_XX属性会被忽略掉,然后设置成默认的包裹内容方式

除了使用这种方式,我们还可以设置item布局的根视图为包裹内容,然后设置内部控件的高度等属性,这样就不会修改显示方式了

你可能感兴趣的:(android,Fragment,LayoutInflater)