Search code examples
androiddialogfragment

DialogFragment call onCreateDialog() after its show()


I have a DialogFragment which has a ProgressBar:

public class DialogFragmentProgress extends DialogFragment {
final static String DTAG = "FileCmd";

View v; 
ProgressBar pb = null;
TextView tv = null;
public void  setMsg(String msg){
    Log.d(DTAG,"ProgressBar: setMsg("+msg+")");
    if (tv != null){
        Log.d(DTAG,"ProgressBar: (tv != null)");
        tv.setText(msg);
    }else{
        Log.d(DTAG,"ProgressBar: (tv == null)");
    }
}

public void  setProgress(int progress){
    Log.d(DTAG,"ProgressBar: setProgress("+progress+")");
    if (pb != null){
        Log.d(DTAG,"ProgressBar: (pb != null)");
        pb.setProgress(progress);
        Log.d(DTAG,"ProgressBar: getProgress() return "+pb.getProgress());
    }else{
        Log.d(DTAG,"ProgressBar: (pb == null)");
    }
}

public static DialogFragmentProgress newInstance() {

    DialogFragmentProgress fragment = new DialogFragmentProgress();

    Log.d(DTAG,"ProgressBar: DialogFragmentProgress.newInstance()!");
    return fragment;
}
public DialogFragmentProgress() {
    // TODO Auto-generated constructor stub
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    LayoutInflater inflater = getActivity().getLayoutInflater();        
    v = inflater.inflate(R.layout.progressbar, null);

    builder.setView(v)
            .setTitle(R.string.progress_prompt)
            .setNegativeButton(R.string.negative, null);

    tv = (TextView)v.findViewById(R.id.progressbar_text);
    pb = (ProgressBar)v.findViewById(R.id.progressbar);

    pb.setMax(100);
    pb.setProgress(10);

    Log.d(DTAG,"ProgressBar: DialogFragmentProgress.onCreateDialog()!");

    return builder.create();
}

}

In MainActivity:

DialogFragmentProgress dfp = new DialogFragmentProgress();
dfp.show(getSupportFragmentManager(), "");
dfp.setProgress(50);
dfp.setMsg(srcFile.getName());

Log output:

11-19 01:42:57.744: D/FileCmd(2095): ProgressBar: setProgress(50)
11-19 01:42:57.744: D/FileCmd(2095): ProgressBar: (pb == null)
11-19 01:42:57.744: D/FileCmd(2095): ProgressBar: setMsg(.qm_guid)
11-19 01:42:57.744: D/FileCmd(2095): ProgressBar: (tv == null)
11-19 01:42:59.494: D/FileCmd(2095): ProgressBar: DialogFragmentProgress.onCreateDialog()!

Please look at the time, which means onCreateDialog() is called very later! So I can not get tv and pb. What's the problem? I need the Dialog show at once and then I can set ProgressBar.


Solution

  • What's the problem?

    Fragment transactions are asynchronous so in your code the fragment's dialog will not be available until the code/method in which you have the show() call will return. Try using getSupportFragmentManager().executePendingTransaction() after the show() call or, much better, change your current code so the setProgress() and setMsg() store the values passed in(and update the views if they are available) followed by using those values when you create the dialog in the onCreateDialog() callback.

    Edit:

    public class DialogFragmentProgress extends DialogFragment {
        final static String DTAG = "FileCmd";
        private String mMsg;
        private int mCurProgress = -1;
    
    public void  setMsg(String msg) {
        mMsg = msg;
        // if we also have the view available update it
        if (pb != null){
        //... current code
    } 
    
    public void  setProgress(int progress){
       mCurProgress = progress;
       // if we also have the view available update it
       if (pb != null){
          // ... current code
    }
    
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
         // current code...
         // if mMsg and mCurProgress are valid it means they were set before the fragment's dialog
         // was created so we need to use them at this moment  
         if (mMsg != null) {
             // we have a valid message so use it at this moment to set the text
             tv.setText(mMsg);
         }
         if (mCurProgress != -1) {
            // we have a valid progress so use it at this moment to set the progress
            pb.setProgress(mCurProgress);
         }
         return builder.create();
    }