Search code examples
androidviewgroup

RemoveView not working


I'm having an unusual error. I have this inside a custom viewgroup. The method receives a view and add it to the layout but i keep getting the same error:

if((ViewGroup)view.getParent() != null){
    ((ViewGroup)view.getParent()).removeView(view);
}

addView(view); <--- Breakpoints puts the error on this line

The error is:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

Using breakpoints around this shows that "view" even after calling removeView onthe parent keep a reference to its parent..

Some people proposed using a runnable to wait a few seconds before adding it to the view. I havent tried this because it seems more a hack than a solution.. Either way i hope someone may be able to help

Thanks!

PS: Not that it should matter but the parent of this view i'm adding is a custom grid layout i made and its parent is a viewpager.

Edit:

I did a little more breakpoints and debugging and from the looks of it the grid effectively remove the view from its child list (debug) but the child view keeps a reference to that same grid in its mParent variable (debug). How is this possible

EDIT:

In activity:

Button button = new Button(mContext);
button.setOnClickListener(mClickListener);
(...)
Random random = new Random();
button.setText(random.nextInt(9999) + " ");

mCurrentGridLayout.addCustomView(button);

In CustomGridLayout viewgroup class:

public void addCustomView(View view){
    if((ViewGroup)view.getParent() != null){
        ((ViewGroup)view.getParent()).removeView(view);
    }

    addView(view);
}

Solution

  • I had that same issue when trying to create a custom banner. I believe it's because of animation during layout, that's why a delay could work. In my case, I made a custom viewgroup class to eliminate the animation delay:

    private class BannerLayout extends LinearLayout {
      public BannerLayout(Context context) {
         super(context);
      }
    
      @Override
      protected void removeDetachedView(View child, boolean animate) {
         super.removeDetachedView(child, false);
      }
    }
    

    Once I did this, everything worked as expected.

    Hope it helps!