zoukankan      html  css  js  c++  java
  • fragment使用不当 导致java.lang.IllegalStateException

    错误信息: 

    java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

    信息补充:

    使用FragmentActvitiy + Fragment

    错误原因:

    在fragment类中需要使用inflater加载布局,

    1 public class fragmentTest extends Fragment {
    2     @Override
    3     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    4         inflater.inflate(R.layout.layout_fragment,container);
    5         return super.onCreateView(inflater, container, savedInstanceState);
    6     }
    7 }

    特别要注意,inlflate()存在一个三个参数的重载,我们先来查看一下源代码中对第三个参数的说明:

     1 /**
     2      * Inflate a new view hierarchy from the specified xml resource. Throws
     3      * {@link InflateException} if there is an error.
     4      * 
     5      * @param resource ID for an XML layout resource to load (e.g.,
     6      *        <code>R.layout.main_page</code>)
     7      * @param root Optional view to be the parent of the generated hierarchy (if
     8      *        <em>attachToRoot</em> is true), or else simply an object that
     9      *        provides a set of LayoutParams values for root of the returned
    10      *        hierarchy (if <em>attachToRoot</em> is false.)
    11      * @param attachToRoot Whether the inflated hierarchy should be attached to
    12      *        the root parameter? If false, root is only used to create the
    13      *        correct subclass of LayoutParams for the root view in the XML.
    14      * @return The root View of the inflated hierarchy. If root was supplied and
    15      *         attachToRoot is true, this is root; otherwise it is the root of
    16      *         the inflated XML file.
    17      */
    18     public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
    19         final Resources res = getContext().getResources();
    20         if (DEBUG) {
    21             Log.d(TAG, "INFLATING from resource: "" + res.getResourceName(resource) + "" ("
    22                     + Integer.toHexString(resource) + ")");
    23         }
    24 
    25         final XmlResourceParser parser = res.getLayout(resource);
    26         try {
    27             return inflate(parser, root, attachToRoot);
    28         } finally {
    29             parser.close();
    30         }
    31     }

    在之前的情景中,我们需要在主界面中动态地添加fragment,所以root是不为空的:

    1. attachToRoot设为true,则会在加载的布局文件的最外层再嵌套一层root布局。

    2. attachToRoot设为false,则root参数失去作用。

    3. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

    因为我们要将fragment加载到当前的activity当中,使用false系统会自动将布局加载到合适的层次。因此正确的使用方法是:

    inflater.inflate(R.layout.layout_fragment,container,false);

    PS:看到一篇博文里讲到对viewroot的一些理解,感觉很有道理。上文中的root其实就是viewroot,它并不是view树的根节点,而是view树的管理者。只是其中有一个变量指向被管理的view树的根节点。一个activity只能有一个viewroot与之绑定

  • 相关阅读:
    openCV使用
    Object-C知识点 (二) 控件的实用属性
    Linux 配置JDK + MyEclipse
    虚拟机+linux+大杂烩
    THREE.js代码备份——webgl
    THREE.js代码备份——webgl
    THREE.js代码备份——canvas_ascii_effect(以AscII码显示图形)
    THREE.js代码备份——canvas
    THREE.js代码备份——canvas_lines(随机点、画线)
    THREE.js代码备份——线框cube、按键、鼠标控制
  • 原文地址:https://www.cnblogs.com/TongWee/p/4907387.html
Copyright © 2011-2022 走看看