Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragments, DialogFragment, and Screen Rotation

I have an Activity that calls setContentView with this XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    >
    <fragment android:name="org.vt.indiatab.GroupFragment"
        android:id="@+id/home_groups"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" />
            <..some other fragments ...>
</LinearLayout>

The GroupFragment extends Fragment, and all is well there. However, I show a DialogFragment from within GroupFragment. This shows correctly, HOWEVER when the screen rotates, I get a Force Close.

What's the proper way to display a DialogFragment from within another Fragment other than DialogFragment.show(FragmentManager, String)?

like image 253
Weston Avatar asked Sep 11 '25 09:09

Weston


2 Answers

There's a bug in the compatibility library that can cause this. Try putting this in you dialogfragment:

@Override
public void onDestroyView() {
  if (getDialog() != null && getRetainInstance())
    getDialog().setOnDismissListener(null);
  super.onDestroyView();
}

I also suggest setting your dialogfragment as retained, so it won't get dismissed after the rotation. Put "setRetainInstance(true);" e.g. in the onCreate() method.

like image 103
Zsombor Erdődy-Nagy Avatar answered Sep 12 '25 23:09

Zsombor Erdődy-Nagy


OK, while Zsombor's method works, this is due to me being inexperienced with Fragments and his solution causes issues with the saveInstanceState Bundle.

Apparently (at least for a DialogFragment), it should be a public static class. You also MUST write your own static DialogFragment newInstance() method. This is because the Fragment class calls the newInstance method in its instantiate() method.

So in conclusion, you MUST write your DialogFragments like so:

public static class MyDialogFragment extends DialogFragment {

    static MyDialogFragment newInstance() {
        MyDialogFragment d = new MyDialogFragment();
        return d;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        ...
    }
}

And show them with:

private void showMyDialog() {
    MyDialogFragment d = MyDialogFragment.newInstance();
    d.show(getFragmentManager(), "dialog");
}

This may be unique to the ActionBarSherlock Library, but the official samples in the SDK documentation use this paradigm also.

like image 25
Weston Avatar answered Sep 13 '25 00:09

Weston