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



相关文章
AutoJs曲线滑动---贝塞尔曲线
AutoJs曲线滑动---贝塞尔曲线
403 0
|
计算机视觉 索引
OpenCV-最值计算cv::minMaxIdx&cv::minMaxLoc
OpenCV-最值计算cv::minMaxIdx&cv::minMaxLoc
393 0
|
存储 监控 算法
LeakCanary 的内存泄露问题排查
LeakCanary 的内存泄露问题排查
160 0
|
12月前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
258 4
Android开发表情emoji功能开发
|
算法 前端开发 Android开发
Android文字基线Baseline算法的使用讲解,Android开发面试题
Android文字基线Baseline算法的使用讲解,Android开发面试题
Android文字基线Baseline算法的使用讲解,Android开发面试题
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
415 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
12月前
|
存储 前端开发 API
DDD领域驱动设计实战-分层架构
DDD分层架构通过明确各层职责及交互规则,有效降低了层间依赖。其基本原则是每层仅与下方层耦合,分为严格和松散两种形式。架构演进包括传统四层架构与改良版四层架构,后者采用依赖反转设计原则优化基础设施层位置。各层职责分明:用户接口层处理显示与请求;应用层负责服务编排与组合;领域层实现业务逻辑;基础层提供技术基础服务。通过合理设计聚合与依赖关系,DDD支持微服务架构灵活演进,提升系统适应性和可维护性。
|
缓存 JavaScript 安全
2022年最新最详细的安装Node.js以及cnpm(详细图解过程、绝对成功)
这篇文章提供了2022年最新最详细的Node.js和cnpm安装教程,包括步骤图解、全局配置路径、cnpm安装命令、nrm的安装与使用,以及如何管理npm源和测试速度。
2022年最新最详细的安装Node.js以及cnpm(详细图解过程、绝对成功)
|
Android开发
Android编译出现Warning: Mapping new ns to old ns的解决方案
Android编译出现Warning: Mapping new ns to old ns的解决方案
953 3
|
前端开发 Java 应用服务中间件
JavaEE:Servlet后端搭建部署 一条龙全教程
JavaEE:Servlet后端搭建部署 一条龙全教程
267 0