49
技术社区[云栖]
You must call removeView() on the child's parent first
首先,Android中的Fragment是什么?
https://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.
这里,贴出处理此问题的几个代码片段,备忘之:
// ...
@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<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:andro android: android:layout_width="fill_parent" android:layout_height="fill_parent" > </FrameLayout>
The specified child already has a parent. You must call removeView() on the child's parent first.的解决办法
出现The specified child already has a parent. You must call removeView() on the child's parent first.这个问题,一般原因是对layout.xml的使用理解不清楚。以xml文件方式来设计界面的布局,如果需要动态的对xml文件中的各类View进行修改的话,在代码中使用时,不能直接使用this.findViewById(R.id.***)来获取xml文件中的每个View,然后再将这些View加入到代码中的Layout中来进行显示。正确的做法应该是使用inflater。
举例如下:
xml布局文件test.xml为:
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="https://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 version="1.0" encoding="utf-8"?>2
<LinearLayout xmlns:android="https://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


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
最后更新:2017-04-02 16:47:43