3

I've got a DialogFragment used to display a TimePickerDialog when pressing a button, and I would like to change the text of the button to the new time set.

My problem is I can't call setOnDismissListener on the DialogFragment from my Activity.

This is my DialogDragment

 public class TimePickerFragment extends DialogFragment
        implements TimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int hour = Application.getSettings().getInt("hour", 11);
        int minute = Application.getSettings().getInt("minute", 11);

        // Create a new instance of TimePickerDialog and return it
        return new TimePickerDialog(getActivity(), this, hour, minute,
                DateFormat.is24HourFormat(getActivity()));
    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        FirstTimeLaunchSettingsActivity.hours = hourOfDay;
        FirstTimeLaunchSettingsActivity.minutes = minute;

    }
}

And this is how I call this DialogFragment

    public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(this.getFragmentManager(), "timePicker");
}

I've already thought making a Handler in my activity which would refresh the Activity every seconde, but that's not how I would like to solve the problem.

I just want, when I close my DialogFragment, my button to be set to the time I've entered.

Thanks for your help.

Vanraj Ghed
  • 1,261
  • 11
  • 23
HypnoZ
  • 55
  • 1
  • 6
  • Possible duplicate of [DialogFragment and onDismiss](http://stackoverflow.com/questions/23786033/dialogfragment-and-ondismiss) – Janki Gadhiya Jun 14 '16 at 10:40

4 Answers4

6

Here is another way to setOnDismissListener() to the dialog fragment

FragmentManager fm = getFragmentManager();

YourDialogFragment dialog = new YourDialogFragment();
dialog.show(fm,"Dialog Name");

fm.executePendingTransactions();
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialogInterface) {
                       //action when dialog is dismissed goes here
                    }
                });

To make sure that FragmentTransaction work has been performed. We need to call

fm.executePendingTransactions();

Otherwise NullPointerException may occur when calling setOnDismissListener().

RedBassett
  • 3,469
  • 3
  • 32
  • 56
Boonya Kitpitak
  • 3,607
  • 1
  • 30
  • 30
  • This one works for me, but can you tell me why we need the `getSupportFragmentManager().executePendingTransactions()`? Without it my app just crashes. Thank you. – Sam Chen Aug 30 '19 at 21:26
  • @SamChen It's something about view not ready kinda thing I think(if you're from web, "DOM ready"). In my situation, even after calling `executePendingTransactions()`, dialog is not found, which causes nullPointer. – Hiro Nov 17 '20 at 21:56
5

You can override the onDismiss(DialogInterface dialog) method, which will be called when the DialogFragment is dismissed. You can also do it from your activity with an inline override:

public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment() {
        @Override
        public void onDismiss(DialogInterface dialog){
            // Add your code here
        }
    };
    newFragment.show(this.getFragmentManager(), "timePicker");
}
Daniel Zolnai
  • 16,487
  • 7
  • 59
  • 71
  • Android Studio gives me a very good warning/error: Fragments should be static! Otherwise they can not be reinstanciated e.g. after orientation change... This might seem to work, but will probably lead to more issues – metinkale38 Jul 10 '17 at 08:37
  • This was just a short example. You can make a non-inline class where you override it the same way. – Daniel Zolnai Jul 10 '17 at 09:23
  • @DanielZolnai In case you make it non-inline, how to you set the dismiss listener from outside of the class, namely from the fragment or activity that calls the dialogfragment? – Hiro Nov 20 '20 at 01:22
  • See the other answers using `setOnDismissListener` – Daniel Zolnai Nov 20 '20 at 08:53
0

You could do it directly inside your already implemented onTimeSet method. You can get the activity where the TimePicker view is embedded and update the button text

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    FirstTimeLaunchSettingsActivity.hours = hourOfDay;
    FirstTimeLaunchSettingsActivity.minutes = minute;

    YourActivityClass activity = (YourActivityClass) getActivity();
    activity.updateButton(hourOfDay + ":" + (minute<10?"0"+minute:minute));
}

Then, inside your activity YourActivityClass, you can update the button as usual:

public void updateButton(String newText) {
    Button yourButton = (Button) findViewById(R.id.yourButtonID);
    yourButton.setText(newText);
}
devnull69
  • 16,402
  • 8
  • 50
  • 61
0

I can't call setOnDismissListener on the DialogFragment from my Activity.

You can, all you have to do is implement the interface in your activity

then Make your Activity implement OnDismissListener

public final class YourActivity extends AppCompatActivity implements DialogInterface.OnDismissListener {

    @Override
    public void onDismiss(final DialogInterface dialog) {
        //Fragment dialog had been dismissed
    }
}

Then just override the onDismiss listerenr in the fragment and call the Activity.

public final class DialogFragmentImage extends DialogFragment {
    @Override
    public void onDismiss(final DialogInterface dialog) {
        super.onDismiss(dialog);
        final Activity activity = getActivity();
        if (activity instanceof DialogInterface.OnDismissListener) {
            ((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
        }
    }

}
Atiq
  • 14,435
  • 6
  • 54
  • 69