Search code examples
androidandroid-fragmentsandroid-dialogfragment

onCreate() callback of DialogFragment not called (where to initialise Views?)


I want to show custom dialog using DialogFragment. However I fail to initialise layout Views before I need to modify them.

This is my DialogFragment class.

public class RemoteProgressDialog extends DialogFragment {

private TextView lockProgress;
private TextView foldProgress;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Dialog_NoActionBar);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.remote_progress_dialog, null);
    lockProgress = (TextView) view.findViewById(R.id.lock_progress);
    return view;
}

public void lockFinished() {
    lockProgress.setCompoundDrawables(
                                    null,
                                    getResources().getDrawable(R.drawable.icn_mycar_sunroof_open),
                                    null, null);
    // TODO: remove
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    showLockProgress(false);
    dismissDialogIfNeeded();
}

public void showLockProgress(boolean show) {
    lockProgress.setVisibility(show ? View.VISIBLE : View.GONE);
}

private void dismissDialogIfNeeded() {
    if (lockProgress.getVisibility() == View.GONE) {
        // TODO: add conditions
        dismiss();
    }
}

I show the dialog in a Fragment like this:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    progressDialog = new RemoteProgressDialog();
}

@Override
public boolean onLongClick(View v) {
    progressDialog.show(getFragmentManager(), REMOTE_PROGRESS_DIALOG);
    progressDialog.showLockProgress(true);
    return true;
}

At first I tried to build the Dialog using AlertDialog.Builder but I was getting NullPointerException because onCreateDialog() method was not performed before showLockProgress() so lockProgress was null. Well, I didn't need AlertDialog anyway so I end up using this approach hoping it would help to solve the problem.

Unfortunately it didn't help. lockProgress is still null when the method showLockProgress() is called. I put a breakpoint in onCreate() and onCreateView() methods of the DialogFragment as well as in onAttach() of hosting Fragment. The one in onAttach() gets triggered so the instance of DialogFragment should be created but neither onCreate() nor onCreateView() seem to be called. When I long-press the button, showLockProgress() is called but lockProgress is still null.

Why aren't my views initialised when the instance of dialog is created or immediately after I call DialogFragment.show() method?


Solution

  • So the problem I guess is that your public method is called before onCreate and etc. because after calling show to your DialogFragment it takes time to initialise the dialog, it's view and all variables. So the way you can handle this the right way in my opinion is just create a boolean variable which you set before showing your DialogFragment. Something like this :

    public class RemoteProgressDialog extends DialogFragment {
    
        private boolean mShowText = false; // default value
    
        private TextView lockProgress;
    
        public void setShowText(boolean showText){
            this.mShowText = showText;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.remote_progress_dialog, null);
        }
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState){
            // initialise your views here
            lockProgress = (TextView) view.findViewById(R.id.lock_progress);
            showLockProgress(mShowText);
        }
    
        public void showLockProgress(boolean show) {
            lockProgress.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    
    }
    

    and you can do something like this before showing your Dialog :

    progressDialog.show(getFragmentManager(), REMOTE_PROGRESS_DIALOG);
    progressDialog.setShowText(true);
    

    So this way you won't get NullPointerException and you can be sure that depending on the boolean which you set, your TextView in RemoteProgressDialog will be hidden or visible when it is initialised.

    Hope this helps!