文档章节

安卓java.lang.IllegalStateException: The specified child already has a parent.解决方案

htq
 htq
发布于 2016/07/26 09:39
字数 1287
阅读 3
收藏 0
点赞 0
评论 0

在使用ViewPager的时候遇到一个错误java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.。经过多次调试及网上查找相关资料,终于弄明白是咋回事,现记录如下:

首先跟大家讲解一下为何会出现该错误,然后再提供自己的错误代码分析错误原因及解决方案。

一为何会报java.lang.IllegalStateException: The specified child already has a parent.错误

根据The specified child already has a parent. You must call removeView() on the child's parent first.的字面意思是一个子View已经存在一个父View,你必须先调用该子视图的父视图的 removeView() 方法,这种情况通常出现在动态添加视图的情况下,出现这种错误的原因是一个子控件只允许存在一个父控件,而很多时候在动态添加视图的时候,我们不知道该子视图是否已存在父视图,当已存在的时候就会报错。

二错误代码分析错误及解决方案:

出错的代码主要是在ViewPager的适配器类的instantiateItem方法中,因为在该方法中我们通常会动态的添加视图。在自己的项目的主界面中定义了一个ViewPager用来循环显示多个GridView,而在主界面中GridView是通过LayoutInflater来动态获取的,代码如下:

LayoutInflater inflater=getActivity().getLayoutInflater();
		View view=inflater.inflate(R.layout.viewpager,null);
		campanyGridView=(GridView) view.findViewById(R.id.campany_gridview_1);
然后将多个campanyGridView添加到List集合中,然后将该ArrayList集合对象作为参数传递给ViewPager对应的Adapter,代码如下:

public class ViewPaperAdapter extends PagerAdapter {

	private ArrayList<View> viewList;
	
	public ViewPaperAdapter(ArrayList<View> viewList) {
		// TODO Auto-generated constructor stub
		this.viewList=viewList;
	}
	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		// TODO Auto-generated method stub
		//super.destroyItem(container, position, object);
		container.removeView(viewList.get(position));
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		
		container.addView(viewList.get(position));
		return viewList.get(position);
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return viewList.size();
	}

	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		// TODO Auto-generated method stub
		return arg0==arg1;
	}

	
	
}
其中PagerAdapter中的instantiateItem方法是用来显示我们添加的视图控件的,其中视图对应的R.layout.viewpager的XML文件如下:

<?xml version="1.0" encoding="utf-8"?>
 
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
   <GridView 
    android:id="@+id/campany_gridview_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:horizontalSpacing="10dp"
    android:verticalSpacing="10dp"
    android:numColumns="3"
  
    ></GridView>

</LinearLayout>
布局很简单,只是在LinearLayout中放了一个GridView控件而已。但是当点击自己项目APP的底部导航按钮(界面类似QQ)来切换界面时报错,即java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.。通过我们上述讲解大家应该能够明白为何出错。


错误分析:因为ViewPager的视图的显示是在PagerAdapter中通过instantiateItem方法来动态添加的,通常我们在该方法中会调用container.addView(viewList.get(position));来添加一个视图,即调用ViewGroup的addView来动态添加控件,但是可以看到在我们的R.layout.viewpager的XML文件中GridView的外部是LinearLayout布局控件,即此时GridView的父控件为LinearLayout,这样就相当于把一个以存在父控件的子控件动态的添加到一个ViewGroup容器中,这是不被允许的,因为一个子控件只允许存在一个父容器控件,因此会报错。

解决方案:通过上述的分析可以很容易找到解决方案:

1去除R.layout.viewpager的XML文件中GridView的外部的LinearLayout布局控件,这样GridView就不存在父容器控件。

2在在PagerAdapter中通过instantiateItem方法中动态添加视图前做一个简单的判断,判断待添加的视图是否已存在父控件,若存在则调用removeAllViews()去除之。代码如下:

public Object instantiateItem(ViewGroup container, int position) {
		// TODO Auto-generated method stub
		View v=viewList.get(position);
		ViewGroup parent = (ViewGroup) v.getParent();
		//Log.i("ViewPaperAdapter", parent.toString());
		if (parent != null) {
		parent.removeAllViews();
		}
		container.addView(viewList.get(position));
		return viewList.get(position);
	}

可以看到第一种方案简单粗暴,但适用性不强,因为我们要添加的一个视图可能很复杂,而不是一个简单的GridView,那么我们必须使用类似LinearLayout的基本布局控件来控制我们的视图,因此第二种方案很显然适用此种情况。


三总结:

ViewGroup的addView()方法不能添加一个已存在父控件的视图,因此在使用类似ViewPager的控件动态添加视图时,要在addView前先判断再添加,上述案例可以扩展为不能使用addView()对同一个控件动态添加两次,因为第一个添加时已表示该子控件已存在父容器控件,第二次添加时尽管其父容器控件是同一个控件,但是相当于该子视图已存在父容器控件,因此仍会报错,如下代码是错误的:

private void initView() {
        LinearLayout viewGroup = (LinearLayout) findViewById(R.id.main_activity_linearlayout);
        LayoutInflater inflater = LayoutInflater.from(this);
        View textView = inflater.inflate(R.layout.test, null);
        viewGroup.addView(textView);
        viewGroup.addView(textView);     //这个地方出错,不能对其添加两次。
    }

解决方案也很简单,对于添加的第二个视图,重新用一个布局文件定义,然后通过inflater.inflate获取再动态添加。

本文转载自:http://blog.csdn.net/htq__/article/details/51290990

共有 人打赏支持
htq

htq

粉丝 19
博文 67
码字总数 1007
作品 3
武汉
android开发中出现的错误集(不断更新)

最后更新:2013-01-16 23.在使用AndroidHttpClient时有如下错误: 01-16 22:18:39.222: E/AndroidHttpClient(26745): java.lang.IllegalStateException: AndroidHttpClient created and nev......

李海珍
2012/03/17
0
6
actvity.findViewById() 与 view.findViewById()

自从学习android的hello world开始 我们就知道了这样一个函数findViewById(),他已经成为了家喻户晓,坑蒙拐骗,杀人越货必备的一个函数(好吧,这句是扯淡) 但一直用也没细致研究过它,直到...

刘小米
2014/12/01
0
1
android幻灯片效果实现-Gallery

最近下载几款手机应用研究了下,发了有些自定义控件惊人的相似,所以我觉得在以后的开发中,对一些控件的复用肯定是很多的,在首页(非载入页)一般都会有一个幻灯片效果,既可以放广告也可以...

zhoulc
2013/06/23
0
0
Layout.addView时报错 java.lang.IllegalStateExcepti...

java.lang.IllegalStateException: The specified child already has a parent. 导致这个异常的原因是因为child View(就是addView方法的实参)已经在一个布局上add过了,如果这时候再去add...

hanQ
2013/01/15
0
0
Custom ViewGroups

Android provides a few ViewGroups like LinearLayout, RelativeLayout, FrameLayout to position child Views. These general purpose ViewGroups have quite a lot of options in them. F......

Jerikc
2015/08/20
0
0
点击按钮弹出Dialog,点击第二次后出现 java.lang.IllegalStateException

不知是什么原因,为什么点击第一次可以正常弹出Dialog,点击第二次却出现错误? 错误显示: java.lang.IllegalStateException: The specified child already has a parent. You must call r...

剑麟
2013/04/07
3.9K
4
android activity ImageView全屏设置

开始接触android也有1月有余了,看了一小部分的教学视频+刚哥的疯狂讲义。总是看着视频做一些Demo,有些木讷。今天尝试终于进入项目中,在项目中巩固知识点。 功能1 project启动 显示欢迎页面...

洛山红茶
06/28
0
0
ViewPager+Fragment 或者 按钮切换Fragme引起的错误:No Activity

1.bug的log java.lang.IllegalStateException: No activity at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075) at android.support.v4.app.FragmentM......

IT丶小生
2014/02/25
0
0
OSC android app LayoutParams改进

android.view.ViewGroup.LayoutParams public static final int FILL_PARENT Since:API Level 1 Special value for the height or width requested by a View. FILLPARENT means that the vi......

JORDANSG
2012/10/13
0
1
【Android】ViewGroup全面分析

一个Viewgroup基本的继承类格式如下: 1 import android.content.Context; 2 import android.view.ViewGroup; 3 4 public class MyViewGroup extends ViewGroup{ 5 6 public MyViewGroup(Co......

gongweixin
2013/05/21
0
8

没有更多内容

加载失败,请刷新页面

加载更多

下一页

python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
21分钟前
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
28分钟前
0
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
36分钟前
0
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
37分钟前
0
0
安装tensorflow-XXX报错

报错: tensorflow-0.5.0-cp27-none-linux_x86_64.whl is not a supported wheel on this platform. 解决: wget https://bootstrap.pypa.io/get-pip.py sudo python2.7 get-pip.py sudo p......

Yao--靠自己
40分钟前
0
0
JVM学习手册(一):JVM模型

一直从事JAVA开发,天天和JVM打交道,仔细想想对JVM还真的不是特别了解,实在是不应该.周六看了许多资料,也算有点心得,记录一下。 JVM内存模型分为5个区域:方法区,堆,虚拟机栈,本地方法栈,程序计...

勤奋的蚂蚁
今天
0
0
转行零基础该如何学Python?这些一定要明白!

转行零基础学Python编程开发难度大吗?从哪学起?近期很多小伙伴问我,如果自己转行学习Python,完全0基础能否学会呢?Python的难度到底有多大?今天,小编就来为大家详细解读一下这个问题。...

猫咪编程
今天
2
0
205. Isomorphic Strings - LeetCode

Question 205. Isomorphic Strings Solution 题目大意:判断两个字符串是否具有相同的结构 思路:构造一个map,存储每个字符的差,遍历字符串,判断两个两个字符串中相同位置字符的差是否相同 Ja...

yysue
今天
0
0
聊聊EurekaRibbonClientConfiguration

序 本文主要研究一下EurekaRibbonClientConfiguration EurekaRibbonClientConfiguration spring-cloud-netflix-eureka-client-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netfl......

go4it
今天
1
0
NoSQL

一、NoSQL介绍 1、NoSQL介绍 NoSQL属于非关系型数据,mysql属于关系型数据库。 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当数据量...

人在艹木中
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部