You must call removeView() on the child's parent first

首先,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.

这里,贴出处理此问题的几个代码片段,备忘之:


// ...
@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:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_main"
    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="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

时间: 2024-08-31 09:19:43

You must call removeView() on the child&#39;s parent first的相关文章

The specified child already has a parent错误

10-05 23:39:48.187: E/AndroidRuntime(12854): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 10-05 23:39:48.187: E/AndroidRuntime(12854): at android.view.Vi

Android异常:The specified child already has a parent.

[Android异常]The specified child already has a parent. You must call removeView() on the child's parent first. 错误信息: Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent

[NHibernate]Parent/Child

系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 [NHibernate]持久化类(Persistent Classes) [NHibernate]O/R Mapping基础 [NHibernate]集合类(Collections)映射  [NHibernate]关联映射 引言  刚刚接触NHibernate的人大多是从父子关系(parent/child type relationship)的建模入手的.父子关系的建模有两种方法.比较简便.直

介绍几个好用的android自定义控件

首先看效果图, 看下这两个界面,第一个中用到了一个自定义的FlowRadioGroup,支持复合子控件,自定义布局: 第二个界面中看到了输入的数字 自动4位分割了吧:也用到了自定义的DivisionEditText控件. 下面直接看源码FlowRadioGroup了: 1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0

各种排序算法汇总

目录 简介 交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 总结 简介 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的过程

android-addView同一个对象两次会出错

问题描述 addView同一个对象两次会出错 //首页按钮 ImageView home=new ImageView(context); home.setImageResource(R.drawable.icon_03); home.setLayoutParams(iconparams); home.setPadding(10, 10, 10, 10); addView(home); //分隔符 ImageView seprator = new ImageView(context); sepra

图片-关于学习《第一行代码》中发现的问题,不敢说是错误,应该是郭霖大神笔误。麻烦各位大神来教训晚辈。。。

问题描述 关于学习<第一行代码>中发现的问题,不敢说是错误,应该是郭霖大神笔误.麻烦各位大神来教训晚辈... _第一处问题:在fragment一章里关于动态加载fragment部分中,要添加的fragment类的代码如下 public class Fragment_3 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedIn

android 出错集

问题1.    java.lang.RuntimeException: Failed to register input channel. Check logs for details. 解决     这个问题应是程序加载(Launcher Pro)  时爆出的,LP是一个主页替代工具,它在程序加载时,当没有释放一些应当释放的资源就会出现    理解起来确有深奥之处,此问题没有真正解决,权当先记下会出现这种情况,备忘 问题2.   An internal error occurred durin

各种排序算法汇总(转)

  目录 简介 交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 总结 简介 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的