首先,Android中的Fragment是什么? http://developer.android.com/guide/topics/fundamentals/fragments.html 场景: 现有两个Fragment(e.g:LoginFragment、HomeFragment)需要在Android程序运行的时候进行动态加载、切换,这种情况下,比较容器出现的一个问题就是:
// java.lang.IllegalStateException: The specified child already has a // parent. You must call removeView() on the child's parent first.这里,贴出处理此问题的几个代码片段,备忘之:
[java] view plain copy print ? <pre>// ... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.i(TAG, "-- onCreateView(...) --"); mRootView = (View) inflater.inflate(R.layout.fragment_login, container, false); return mRootView; } // 当FragmentActivity动态切换Fragment的时候,上面代码片段中的container设置为null或者其后的参数设置为false, // 否则会报出异常: // java.lang.IllegalStateException: The specified child already has a // parent. You must call removeView() on the child's parent first. // 另外,对fragment进行remove操作前记得进行非空判断 // ... protected void goHome() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); HomeFragment homeFragment = new HomeFragment(); if (null == getFragmentManager().findFragmentByTag("tag_home")) { transaction.add(R.id.fragment_main, homeFragment, "tag_home"); } if (null != getFragmentManager().findFragmentByTag("tag_login")) { transaction.remove(getFragmentManager().findFragmentByTag("tag_login")); } transaction.replace(R.id.fragment_main, homeFragment) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); }</pre>main.xml<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_main" android:layout_width="fill_parent" android:layout_height="fill_parent" > </FrameLayout> </pre> <pre></pre> <br> <h2><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/easywu/archive/2010/12/11/340375.html">The specified child already has a parent. You must call removeView() on the child's parent first.的解决办法</a> </h2> 出现The specified child already has a parent. You must call removeView() on the child's parent first.这个问题,一般原因是对layout.xml的使用理解不清楚。<br> 以xml文件方式来设计界面的布局,如果需要动态的对xml文件中的各类View进行修改的话,在代码中使用时,不能直接使用this.findViewById(R.id.***)来获取xml文件中的每个View,然后再将这些View加入到代码中的Layout中来进行显示。正确的做法应该是使用inflater。<br> <br> 举例如下:<br> <p>xml布局文件test.xml为:</p> <p></p> <div style="border-bottom:#cccccc 1px solid; border-left:#cccccc 1px solid; padding-bottom:4px; background-color:#eeeeee; padding-left:4px; width:98%; padding-right:5px; font-size:13px; word-break:break-all; border-top:#cccccc 1px solid; border-right:#cccccc 1px solid; padding-top:4px"> <span style="color:#008080">1</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><span style="color:#0000ff"><?</span><span style="color:#ff00ff">xml version="1.0" encoding="utf-8"</span><span style="color:#0000ff">?></span><br> <span style="color:#008080"> 2</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><span style="color:#0000ff"><</span><span style="color:#800000">LinearLayout </span><span style="color:#ff0000">xmlns:android</span><span style="color:#0000ff">="http://schemas.android.com/apk/res/android"</span><span style="color:#ff0000"><br> </span><span style="color:#008080"> 3</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:orientation</span><span style="color:#0000ff">="vertical"</span><span style="color:#ff0000"> android:layout_width</span><span style="color:#0000ff">="fill_parent"</span><span style="color:#ff0000"><br> </span><span style="color:#008080"> 4</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_height</span><span style="color:#0000ff">="fill_parent"</span><span style="color:#0000ff">></span><br> <span style="color:#008080"> 5</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><br> <span style="color:#008080"> 6</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <span style="color:#0000ff"><</span><span style="color:#800000">TextView </span><span style="color:#ff0000">android:id</span><span style="color:#0000ff">="@+id/tv1"</span><span style="color:#ff0000"> android:layout_gravity</span><span style="color:#0000ff">="center_vertical"</span><span style="color:#ff0000"><br> </span><span style="color:#008080"> 7</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_width</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"> android:layout_height</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"><br> </span><span style="color:#008080"> 8</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> </span><span style="color:#0000ff">/></span><br> <span style="color:#008080"> 9</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><br> <span style="color:#008080">10</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <span style="color:#0000ff"><</span><span style="color:#800000">TextView </span><span style="color:#ff0000">android:id</span><span style="color:#0000ff">="@+id/tv2"</span><span style="color:#ff0000"> android:layout_gravity</span><span style="color:#0000ff">="center_vertical"</span><span style="color:#ff0000"><br> </span><span style="color:#008080">11</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_width</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"> android:layout_height</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"><br> </span><span style="color:#008080">12</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> </span><span style="color:#0000ff">/></span><br> <span style="color:#008080">13</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><br> <span style="color:#008080">14</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <span style="color:#0000ff"><</span><span style="color:#800000">TextView </span><span style="color:#ff0000">android:id</span><span style="color:#0000ff">="@+id/tv3"</span><span style="color:#ff0000"><br> </span><span style="color:#008080">15</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_gravity</span><span style="color:#0000ff">="center_vertical"</span><span style="color:#ff0000"> android:layout_width</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"><br> </span><span style="color:#008080">16</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_height</span><span style="color:#0000ff">="wrap_content"</span><span style="color:#ff0000"> </span><span style="color:#0000ff">/></span><br> <span style="color:#008080">17</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><br> <span style="color:#008080">18</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <span style="color:#0000ff"><</span><span style="color:#800000">ImageView </span><span style="color:#ff0000">android:src</span><span style="color:#0000ff">="@drawable/line"</span><span style="color:#ff0000"> android:layout_width</span><span style="color:#0000ff">="fill_parent"</span><span style="color:#ff0000"><br> </span><span style="color:#008080">19</span><span style="color:#ff0000"><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> android:layout_height</span><span style="color:#0000ff">="fill_parent"</span><span style="color:#ff0000"> </span><span style="color:#0000ff">/></span><br> <span style="color:#008080">20</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><br> <span style="color:#008080">21</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"><span style="color:#0000ff"></</span><span style="color:#800000">LinearLayout</span><span style="color:#0000ff">></span></div> <br> 如果你需要使用这个布局XML文件,并根据自己的需要,将其中三个TextView的文字做更改,则在代码中应该这样去使用:<br> <div style="border-bottom:#cccccc 1px solid; border-left:#cccccc 1px solid; padding-bottom:4px; background-color:#eeeeee; padding-left:4px; width:98%; padding-right:5px; font-size:13px; word-break:break-all; border-top:#cccccc 1px solid; border-right:#cccccc 1px solid; padding-top:4px"> <span style="color:#008080"> 1</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <img alt="" src="http://www.blogjava.net/Images/dot.gif"><img alt="" src="http://www.blogjava.net/Images/dot.gif"><br> <span style="color:#008080"> 2</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> LayoutInflater inflate = (LayoutInflater)<br> <span style="color:#008080"> 3</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> getSystemService(Context.LAYOUT_INFLATER_SERVICE);<br> <span style="color:#008080"> 4</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> LinearLayout layout = (LinearLayout)inflate.inflate(R.layout.poemshowlist, <span style="color:#0000ff">null</span>); <br> <span style="color:#008080"> 5</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <br> <span style="color:#008080"> 6</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> ((TextView)layout.findViewById(R.id.tv1)).setText(text1);<br> <span style="color:#008080"> 7</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> ((TextView)layout.findViewById(R.id.tv2)).setText(text2);<br> <span style="color:#008080"> 8</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> ((TextView)layout.findViewById(R.id.tv3)).setText(text3);<br> <span style="color:#008080"> 9</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <br> <span style="color:#008080">10</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> LinearLayout ll= <span style="color:#0000ff">new</span> LinearLayout(<span style="color:#0000ff">this</span>);<br> <span style="color:#008080">11</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> ll.addView(layout);<br> <span style="color:#008080">12</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> setContentView(ll);<br> <span style="color:#008080">13</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <br> <span style="color:#008080">14</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"> <img alt="" src="http://www.blogjava.net/Images/dot.gif"><img alt="" src="http://www.blogjava.net/Images/dot.gif"><br> <span style="color:#008080">15</span><img alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif"></div> <br> <br> <br> <p></p> // ... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.i(TAG, "-- onCreateView(...) --"); mRootView = (View) inflater.inflate(R.layout.fragment_login, container, false); return mRootView; } // 当FragmentActivity动态切换Fragment的时候,上面代码片段中的container设置为null或者其后的参数设置为false, // 否则会报出异常: // java.lang.IllegalStateException: The specified child already has a // parent. You must call removeView() on the child's parent first. // 另外,对fragment进行remove操作前记得进行非空判断 // ... protected void goHome() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); HomeFragment homeFragment = new HomeFragment(); if (null == getFragmentManager().findFragmentByTag("tag_home")) { transaction.add(R.id.fragment_main, homeFragment, "tag_home"); } if (null != getFragmentManager().findFragmentByTag("tag_login")) { transaction.remove(getFragmentManager().findFragmentByTag("tag_login")); } transaction.replace(R.id.fragment_main, homeFragment) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); }main.xml [html] view plain copy print ? <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_main" android:layout_width="fill_parent" android:layout_height="fill_parent" > </FrameLayout> <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_main" android:layout_width="fill_parent" android:layout_height="fill_parent" > </FrameLayout>xml布局文件test.xml为:
1 <? xml version="1.0" encoding="utf-8" ?> 2 < LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" 3 android:orientation ="vertical" android:layout_width ="fill_parent" 4 android:layout_height ="fill_parent" > 5 6 < TextView android:id ="@+id/tv1" android:layout_gravity ="center_vertical" 7 android:layout_width ="wrap_content" android:layout_height ="wrap_content" 8 /> 9 10 < TextView android:id ="@+id/tv2" android:layout_gravity ="center_vertical" 11 android:layout_width ="wrap_content" android:layout_height ="wrap_content" 12 /> 13 14 < TextView android:id ="@+id/tv3" 15 android:layout_gravity ="center_vertical" android:layout_width ="wrap_content" 16 android:layout_height ="wrap_content" /> 17 18 < ImageView android:src ="@drawable/line" android:layout_width ="fill_parent" 19 android:layout_height ="fill_parent" /> 20 21 </ LinearLayout > 如果你需要使用这个布局XML文件,并根据自己的需要,将其中三个TextView的文字做更改,则在代码中应该这样去使用: 1 2 LayoutInflater inflate = (LayoutInflater) 3 getSystemService(Context.LAYOUT_INFLATER_SERVICE); 4 LinearLayout layout = (LinearLayout)inflate.inflate(R.layout.poemshowlist, null); 5 6 ((TextView)layout.findViewById(R.id.tv1)).setText(text1); 7 ((TextView)layout.findViewById(R.id.tv2)).setText(text2); 8 ((TextView)layout.findViewById(R.id.tv3)).setText(text3); 9 10 LinearLayout ll= new LinearLayout( this); 11 ll.addView(layout); 12 setContentView(ll); 13 14 15