1

I have a ViewSwitcher and want to add views to it:

    // initialize views
    final ViewSwitcher switcher = new ViewSwitcher(this);
    layMenu = (LinearLayout)findViewById(R.id.menu_main_view);
    final LevelPicker levelPicker = new LevelPicker(getApplicationContext());   

    (//)switcher.addView(layMenu);
    (//)switcher.addView(findViewById(R.layout.menu_switcher));

One is a custom view, the other one from XML. I commented one of them, but they both seem to throwIllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

I tried doing several things like putting the views in a 'container' first (another layout), or tried removeView((View)getParent), like I believe the logcat tries to say..

Here's my xml file (in a nutshell):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_main_view">

<TextView>
</TextView>

<LinearLayout>
    <Button></Button> //couple of buttons
</LinearLayout>

</LinearLayout> //this is the parent i guess

My first guess was that all childs had to be in 1 parent, which in my case is the LinearLayout. This didn't seem to work.

Thanks

user717572
  • 3,626
  • 7
  • 35
  • 60

1 Answers1

0

yes any View instance should have only 1 parent according to the source file {android}/frameworks/base/core/java/android/view/View.java

in order to remove a View instance from its container, you need to do following things:

// View view = ...
ViewParent parent = view.getParent();
if (parent instanceof ViewGroup) {
    ViewGroup group = (ViewGroup) parent;
    group.removeView(view);
}
else {
    throw new UnsupportedOperationException();
}

I guess you invoked Activity.this.setContentView(R.layout....) on the xml layout file. in this case, the parent of the LinearLayout view was another LinearLayout instance provided by a "decorate window".

it's often not a good practice to remove the only child of the "decorate window". you'd better create the children of the ViewSwitcher explicitly:

// Activity.this.setContentView(viewSwitcher);
// final Context context = Activity.this;
final android.view.LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layMenu = inflater.inflate(R.layout...., null /* container */);
final View menuSwitcher = inflater.inflate(R.layout...., null /* container */);
viewSwitcher.addView(layMenu);
viewSwitcher.addView(menuSwitcher);
chyou
  • 126
  • 1
  • I'm confused. i.e. my LevelPicker is a custom Class extending LinearLayout, where in the constructor I call this.addView(inflater.inflate (R.layout...). How would I do this correctly? Also what should be the contents of the Xml when doing what youd described above? – user717572 Dec 31 '11 at 13:42
  • LayoutInflater is right for the xml layout file. in the LevelPicker case, just simply create the instance by the java new operator. or if you like, you can also put use an xml file to describe UI based on it just like you use the normal LinearLayout in the xml. the only difference is you should use the qualified name of the LevelPicker as the xml tag, i.e. – chyou Jan 02 '12 at 12:24
  • any valid layout xml file as you used in the Activity.this.setContentView() calling can be "inflated" by the LayoutInflater. – chyou Jan 02 '12 at 12:26