The specified child already has a parent. You must call removeView() on the child's parent first.
上面这个异常相信大家在开发中时不时会遇到过,刚接触这个异常时,是会有点让人摸不着头脑,那么上面这个异常是什么意思了?
其实就是:子view已经拥有一个父布局,我们需要先让该子view的父布局调用一下 removeView()方法。也就是说一个子view只能拥有一个父view,这种情况往往会出现在动态添加view上,我们添加子view的时候,并不知道子view是不是已经拥有一个父view,如果说已经存在一个父view那么就会报以上错误。
下面来说下遇到的几种场景
场景1:
在Activity的 main_layout.xml中动态添加 Fragment时,如果使用不当,也会报这个异常
那么为什么会报这个异常了 ?问题就出现在 inflater.inflate(R.layout.content_fragment, container, true); 函数发生了错误。
第三个参数的布尔值决定了是否将 container 作为根对象返回。
true ---表示就将这个 container作为根对象返回
false ----仅仅是将这个root 对象的 LayoutParams属性参数附加到 Resource对象的根布局对象上,也就是布局文件resource的最外层的View上。
因为代码中是要把 Fragment(content_fragment)放在主页的 activity_main_for上的,主页面是根布局对象,调用 inflate是为了得到 View对象,然后附加到 根对象 content_fragment的布局上,所以显然,第三个参数要设置成 false.
public class MainForActivity extends FragmentActivity implements OnClickListener {
private Button mTabWeixin;
private contentFragment mWeixin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWeixin = new contentFragment();
setContentView(R.layout.activity_main_for);
mTabWeixin = (Button) findViewById(R.id.tab_bottom_weixin);
// 设置默认的Fragment
setDefaultFragment();
}
private void setDefaultFragment() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
mWeixin = new contentFragment();
transaction.replace(R.id.id_content, mWeixin);
transaction.commit();
}
}
public class contentFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.content_fragment, container, true);
}
}
场景2:
PagerAdapter的 instantiateItem(ViewGroup arg0,int ar1) ViewPager在动态 AddView时也会出现 上述异常.
比如,ViewPager在滑动到某一页时,要去通过 AddView()动态添加一个 ImageView,就可能会出现上面异常情况
所以在 instantiateItem()函数中 我们应该在 container.addView()之前判断一下,子View的父View是否为空,所以代码可以这样改写
public Object instantiateItem(ViewGroup container, int position) {
ViewGroup viewGroup = images.get(position).getParent();
if (viewGroup != null) {
viewGroup.removeView(images.get(position));
}
container.addView(images.get(position), 0);
LogUtil.i("viewpagers", "instantiateItem" + position + "");
return images.get(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(images.get(position), 0);
LogUtil.i("viewpagers", "instantiateItem" + position + "");
return images.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
LogUtil.i("viewpagers", "destroyItem" + position + "");
container.removeView(images.get(position));
}
场景3:
RecyclerView.Adapter中的 onCreateViewHolder(ViewGroup group,int viewType)报上述错误
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MyApplication.getInstance()).inflate(R.layout.content_list_item,parent,true);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
content_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity">
<TextView
android:id="@+id/content_list_title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:textColor="#000"
android:gravity="center_vertical"
android:textSize="15dp"/>
<!--<android.support.constraint.Guideline-->
<!--app:layout_constraintTop_toBottomOf="@id/content_list_title"-->
<!--app:layout_constraintLeft_toLeftOf="parent"-->
<!--app:layout_constraintRight_toRightOf="parent"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="2px"/>-->
</android.support.constraint.ConstraintLayout>
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/main_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="20dp"
android:text="这是一个关于App体积包裁剪之路"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recycler_list"
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="@id/main_title"
android:layout_marginBottom="20dp"
android:layout_marginTop="10dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>