Search code examples
androidscreen-orientationandroid-dialogfragment

DialogFragment members becomes null after screen rotation


I am getting a frustrating problem about the dialogfragment when screen orientation changes. The member object (a TextView) becomes null when I use it in a handler, but it was inflated and assigned in onCreateView after the rotation of screen.

Basically I have a button in the dialog to let users to choose file from another activity. After that the chosen file path will be printed on the textview.

So I have:

mHandler = new Handler();

public View onCreateView(...) {
    View rootView = ....
    mPathView = (TextView)rootView.findViewById(...);
    Log.d("test", String.format("%s", mPathView.toString());
    ...
}

And I have a method, which is called in onActivityResult of the attached activity:

public void onFileSelected(...) {
    if(reqeustCode==Activity.RESULT_OK) {
         ...
         mHandler.post(new Runnable() {
             public void run() {
                 Log.d("test", String.format("mPathView==null:%b", mPathView==null));
                 if(mPathView!=null) {
                     mPathView.setText(path);
                 }
             }
         }
         return;
     }
     //Error handling here
 }

If I check the logcat, I can see something like:

09-20 16:13:51.264:     test    android.widget.TextView@41cc15e8
09-20 16:13:52.412:     test    android.widget.TextView@41cc15f8 (after rotation)
09-20 16:13:56.129:     test    mPathView==null: true (after file selected)

I have tried the retainInstance in the onCreate, but it did not solve this plus introducing new problem: the savedInstanceState is always null in onCreateView.

I am also aware that the instance is recreated after the rotation of screen. But what I don't understand is that after the re-creation, the mPathView is assigned (as the logcat log indicated).

I suspect it is somehow related to the activity re-creation, because I have a instance of the dialog created in onCreate in the Activity... so in the onActivityResult, the reference of the dialog is no longer the displayed one. But at this time, I have not verified it and have not got a good idea of keep the instance of the dialog.

I have read quite some post in StackOverflow but still cannot get it work... Any help is greatly appreciated!


Solution

  • Now I have verified what I've suspected and that is the cause.

    So I have to wrote some not-good-looking code to make it work: In the activity I added a method

    public void setDialogInstance(FileSelectDialog dialog) {
        mDialog = dialog;
    }
    

    And in the FileSelectDialog, I override the onActivityCreated method

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(..);
        try {
            MainActivity host = (MainActivity)getActivity();
            host.setDialogInstance(this);
        } catch(ClassCastException e) {}
    }
    

    At first I tried to call the setDialogInstance method in onAttach method, but only to find it is before the activity's onCreate.

    I think maybe an interface can be introduced so that the DialogFragment does not need to know the host's specific activity.