سؤال

I'm working on 3.0 for the first time. I want to add fragments dynamically , but its shown error:-

10-18 18:29:11.215: ERROR/AndroidRuntime(3550): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

XML code

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frags">

<ListView
        android:id="@+id/number_list"
        android:layout_width="250dip"
        android:layout_height="match_parent" />

<FrameLayout
        android:id="@+id/the_frag"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Activity

public class FragmentExampleActivity extends Activity implements
    OnItemClickListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ListView l = (ListView) findViewById(R.id.number_list);
    ArrayAdapter<String> numbers = new ArrayAdapter<String>(
            getApplicationContext(), android.R.layout.simple_list_item_1,
            new String[] { "one", "two", "three", "four", "five", "six" });
    l.setAdapter(numbers);
    l.setOnItemClickListener(this);
}

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    Fragment f = new FragmentExample();

    FragmentTransaction ft = getFragmentManager().beginTransaction();       
    ft.replace(R.id.the_frag, f);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.addToBackStack(null);
    ft.commit();

}
}


public class FragmentExample extends Fragment {
private int nAndroids=1;

public FragmentExample() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
    int n;

    View l = inflater.inflate(R.layout.textlay,container);
    TextView tv = (TextView) l.findViewById(R.id.textView1);
    tv.setText("value "+nAndroids);

    return l;
}

}

Plz put some light on , where i'm going wrong :(

هل كانت مفيدة؟

المحلول

Instead of using

View l = inflater.inflate(R.layout.textlay,container);

you should use

View l = inflater.inflate(R.layout.textlay, container, false);

or alternatively

View l = inflater.inflate(R.layout.textlay, null );

I strongly suggest you to use, the version of inflate which takes three parameters. Android use the container only for the layout's params purpose. Passing false as third parameter, prevents the addition of textlay, to container and fixes your issue

نصائح أخرى

if in onCreateView() , you want to reuse view , then you can deal with onDestroyView()

@Override
public void onDestroyView() {
    super.onDestroyView();
    if (view != null) {
        ViewGroup parentViewGroup = (ViewGroup) view.getParent();
        if (parentViewGroup != null) {
            parentViewGroup.removeAllViews();
        }
    }
}

or you can use third argument and pass it as a false.

inflater.inflate(R.layout.sample_fragment, container,false);

it means that don't attach current view to root.

The following solves multiple problems:

public static View contentView;

public static class MenuCardFrontFragment extends Fragment {
    public MenuCardFrontFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        try
        {
            LinearLayout frontLayout = (LinearLayout)inflater.inflate(R.layout.content_card, container, false);
            // modify layout if necessary
            return contentView = frontLayout;
        } catch (InflateException e) {
            return contentView;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (contentView != null) {
            ViewGroup parentViewGroup = (ViewGroup) contentView.getParent();
            if (parentViewGroup != null) {
                parentViewGroup.removeAllViews();
            }
        }
    }
}
  1. If fragments shows with animation and user forced to repeat the animation before it's over. ex: pressing menu button twice before the menu fragment finishes animating and appear. (this got solved by the onDestryView from user2764384)

  2. If inflate method called with specifying the container to get container lay outing. it looks like that cases a problem because at the 2nd time that happened the old container already have a view. so if that exception happen it will be caught and returns the old view contentView.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top