您的位置:首页 > 编程语言 > Java开发

java.lang.IllegalStateException

2015-12-02 15:46 477 查看
报错:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child’s parent first.

导读:最近给我的项目添加一个新功能,引用前面的写过的一个输入框,该输入框是一个继承于fragment的子类;我将其使用在了一个布局文件中,该布局文件又是一个fragment类的布局文件;而这个类又是我写的一个有三个fragment成员的viewpager中的一个。所以在循环点击多次该fragment对应的Tab的时候会报该错。说的可能有点模糊,但由于知识有限也不知道怎么描述了。大体上的框架就是:一个ViewPager里面包含3个fragment:fragment1,fragment2,fragment3;而fragment3使用的布局文件layout里面引用了一个fragment的类。

布局代码:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/bj_qt"
android:orientation="horizontal">

<LinearLayout
android:id="@+id/tpm11"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/circlegroupchatlist"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ededec"
android:cacheColorHint="#00000000"
android:divider="#d2d2d6"
android:dividerHeight="0.5dip" />

<LinearLayout
android:id="@+id/chattx"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal"
android:visibility="gone" >

<ImageView
android:id="@+id/dfxx"
android:layout_width="0dip"
android:layout_height="150dip"
android:layout_gravity="right"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_weight="1" />

<ImageView
android:id="@+id/zjxx"
android:layout_width="0dip"
android:layout_height="150dip"
android:layout_gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/dhbj_ty"
android:gravity="center"
android:orientation="vertical" >

<fragment
class="com.gymhd.hyd.ui.activity.frament.**InputFrament2**"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/inpute"
tools:layout="@layout/fragment_inpute2" />

</LinearLayout>

</LinearLayout>

<RelativeLayout
android:id="@+id/num_qd"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:visibility="visible"
android:background="@drawable/bg_qd"
>
<TextView
android:id="@+id/qd_unread_num"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/shap_yx"
android:text="15"
android:textColor="@color/white"
android:gravity="center"
/>
<TextView
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/ql_qd"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</RelativeLayout>


代码注释:以上代码中的InputFrament2就是那个fragment输入框的引用了,也是问题所在。

出错分析与讲解

我在刚遇到该问题的时候就试着现将其注释掉果然就没问题了,故确定问题出在该处,然后接着上网、问大神查找解决方法;最后总结了出错原因,其实从报错的字面意思大致也能知道一点的那就是父类被onDestroy了,子类的view还没被回收。这是怎么回事呢?按理来说父类都被干掉了,子类不应该还在的啊。通过一些博文的了解解释是“这是由于某位写代码的员工抱怨没发奖金,稍稍偷懒了,少写了一部分代码,没有考虑到Fragment再去嵌套Fragment的情况。”所以造成了如今苦逼的我们。

解决方法

既然知道了问题所在解决应该就简单了,可我不知道是我遇到的问题特殊还是怎么回事,我尝试了很多种网上的方法都没搞定,不过伤天不负有心人啊,最后我终于搞定了。我也总结到了一个经验,那就是有时候不能照搬别人的方法,多动脑筋思考才能找到最适合自己的解决方案。好了不长篇大论了,还是说说我怎么解决的吧!

1、发现问题:

通过打印日志发现viewpager里面的fragment只能保留两个第三个总会被ondestroy,在快用到他的时候再oncreate。但是在销毁fragment3的时候没有对其子类的InputFrament2进行处理。

2、解决问题:

package com.gymhd.hyd.ui.activity.frament;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.gymhd.hyd.common.HiydApplication;
import com.gymhd.hyd.entity.CircleThreeMemberPartVar;
import com.gymhd.hyd.entity.GroupChatRecordPartVar;
import com.gymhd.hyd.ui.activity.Sing_for_Group;
import com.gymhd.hyd.ui.adapter.CircleGroupChatAdp;
import com.gymhd.hyd.ui.slefdefined.TastView;
import com.gymhd.hyd.util.LogUtil;

import wen.ddsjw.mhd.R;

public class CircleGroupChatFrament extends Fragment {
private View                circleGroupView;
private ListView            listView;
private RelativeLayout      relativeLayout;
private CircleGroupChatAdp  circleGroupChatAdp;
private CircleThreeMemberPartVar circleThreeMemberPartVar;

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LogUtil.logw(getClass().getName(), "i am circlegroup oncreateview");

String gno_now = HiydApplication.circlePropertyPartVar
.getCirclePropertyDataSource().get("gno");
circleThreeMemberPartVar = HiydApplication.circleThreeMemberPartVar;
circleThreeMemberPartVar.setCircleGroupChatFrament(this);

***if (circleGroupView == null) {
circleGroupView = inflater.inflate(R.layout.act_circlegroupchat, null);
}***
circleGroupChatAdp = new CircleGroupChatAdp(getActivity(), gno_now);
listView = (ListView) circleGroupView.findViewById(R.id.circlegroupchatlist);
relativeLayout = (RelativeLayout) circleGroupView.findViewById(R.id.num_qd);

operationView();

return circleGroupView;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LogUtil.logw(getClass().getName(), "i am circlegroup oncreate");
if(savedInstanceState==null)
return;
}
@Override
public void onResume() {
super.onResume();
}

@Override
public void onPause() {
super.onPause();
TastView.hide(true);
}

@Override
public void onDestroy() {
super.onDestroy();
LogUtil.logw(getClass().getName(), "i am circlegroup ondestroy");
***ViewGroup parent = (ViewGroup) circleGroupView.getParent();
if (parent != null) {
parent.removeAllViews();
}***
}

public void updateUI() {
if (null != circleGroupChatAdp) {
new Handler(Looper.getMainLooper()).postAtFrontOfQueue(new Runnable() {

@Override
public void run() {
circleGroupChatAdp
.setData(circleThreeMemberPartVar.getdataCircleGroup());
circleGroupChatAdp.notifyDataSetChanged();
selectLastOne();
}
});

}
}

/**
* 让列表显示最后一行
*/
private void selectLastOne() {
listView.setSelection(circleGroupChatAdp.getCount());
}

private void operationView() {
listView.setAdapter(circleGroupChatAdp);
GroupChatRecordPartVar.circleGroupChatFrament = this;

relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getActivity(),
Sing_for_Group.class);
startActivity(i);
}
});
}
}


代码注释:重点就是在onCreateView中的circleGroupView 空判断,还有onDestroy中的销毁操作

参考链接:

http://www.tuicool.com/articles/2eM32a

/article/8746641.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: