Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Callback When DialogFragment is Dismissed

Tags:

I want to launch a dialog with a custom layout, which I've implemented via a DialogFragment. (I basically just changed onCreateView() and added button handlers). The dialog lets the user quickly change an important setting.

This dialog will be launched from several different activities. The different activities don't have much in common, except that they need to refresh after the user makes a change to the setting. They don't need to get any information from the dialog; they merely need to know when it's closed (dismissed).

What I've Tried

I tried having the activity refresh in onResume(), but launching and dismissing a dialog never seems to call this method. (So I'm not sure why it even exists, but that's probably a topic for another question.)

Next, I tried adding a DialogInterface.OnDismissListener to the dialog:

public static void showMyDialog(OnDismissListener listener, Activity activity) {     DialogFragment fragment = new MyDialogFragment();     fragment.show(activity.getFragmentManager(), "date");     activity.getFragmentManager().executePendingTransactions();//A     fragment.getDialog().setOnDismissListener(listener);//B } 

When I originally left out the line A, I got a NullPointerException on line B because the dialog is null at that point. Following the advice of this SO answer, I put in the call to executePendingTransaction(). This causes an IllegalStateException on line B, with the message "OnDismissListener is already taken by DialogFragment and cannot be replaced." I also tried putting setOnDismissListener() before the call to show(), but that always caused a NullPointerException.

I then read this other SO answer, which says the original asker was "calling getDialog() too early in the DialogFragment's life cycle." So I tried adding a constructor to my DialogFragment:

public MyDialogFragment(SomeCallback illTakeAnythingICanGet) {     //I'll store the callback here and call it later } 

Unfortunately, adding a constructor made Android Lint freak out with a fatal warning, and when I looked it up, I found a comment in this question that seems to say this approach will make it impossible to deal with the user rotating the screen while the dialog is open.

The Question

How can an activity figure out when a DialogFragment has closed (been dismissed) in a way that won't break my app if the user rotates the screen? Should I be using something else besides a DialogFragment?

like image 716
Impatient Dev Avatar asked Jun 10 '14 22:06

Impatient Dev


People also ask

Is DialogFragment deprecated?

This class was deprecated in API level 28. Use the Support Library DialogFragment for consistent behavior across all devices and access to Lifecycle.

How do you dismiss a DialogFragment?

tl;dr: The correct way to close a DialogFragment is to use dismiss() directly on the DialogFragment. Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog. Dismiss the fragment and its dialog.

How do I know if DialogFragment is showing?

This is gonna be disappointing to you "great" finding but just call progressDialog. showDialog() twice back-to-back and you will get two dialogs. Because show is asynchronous and your findFragmentByTag(TAG) == null check will be true until dialog is actually added by system.

What is the difference between dialog & DialogFragment?

Show activity on this post. Dialog: A dialog is a small window that prompts the user to make a decision or enter additional information. DialogFragment: A DialogFragment is a special fragment subclass that is designed for creating and hosting dialogs.


2 Answers

This is just a longer explanation of harism's comment in case anyone else has the same problem I did.

You can accomplish what I wanted by creating an interface like this:

public interface MyDialogCloseListener {     public void handleDialogClose(DialogInterface dialog);//or whatever args you want } 

Have the activity that launches your dialog (DialogFragment) implement this interface. Then give that DialogFragment the following method:

public void onDismiss(DialogInterface dialog) {     Activity activity = getActivity();     if(activity instanceof MyDialogCloseListener)         ((MyDialogCloseListener)activity).handleDialogClose(dialog); } 
like image 184
Impatient Dev Avatar answered Sep 18 '22 15:09

Impatient Dev


More explanatory code for someone to do the same.

Create the interface as:

package com.example.dialoglistener; import android.content.DialogInterface;  public interface MyDialogCloseListener {     public void handleDialogClose(DialogInterface dialog); } 

Implement the interface in activity as:

MyDialogCloseListener closeListener = new MyDialogCloseListener() {         @Override         public void handleDialogClose(DialogInterface dialog) {                                                  //do here whatever you want to do on Dialog dismiss         } }; 

Write a DismissListener in DialogFragement as

public void DismissListener(MyDialogCloseListener closeListener) {         this.closeListener = closeListener; } 

call DismissListener from your activity as:

dialogFragementObject.DismissListener(closeListener); 

and finally write onDismiss method

@Override     public void onDismiss(DialogInterface dialog) {         super.onDismiss(dialog);         if(closeListener != null) {             closeListener.handleDialogClose(null);         }      } 
like image 20
shaby Avatar answered Sep 18 '22 15:09

shaby