View系列:View问题:The specified child already has a parent. You must call removeView() on the child‘s pa

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>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值