Is there any way I can detect when a DialogFragment is dismissed, so that i can update its parent fragment?
You can add a listener and override the onDismiss of your fragment dialog :
public class DismissDialog extends DialogFragment {
private DialogInterface.OnDismissListener onDismissListener;
public void setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
this.onDismissListener = onDismissListener;
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (onDismissListener != null) {
onDismissListener.onDismiss(dialog);
}
}
}
Then, on the parent, you set a listener :
DismissDialog d = new DismissDialog();
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
d.show(getSupportFragmentManager(), "sometag");
Override onDismiss() of DialogFragment, or when building the underlying dialog, set a listener with setOnDimissListener().
I tried @Gazer answer, it doesn't work for me, I am using different fragment class
import android.app.Fragment;
But I got this working
Create an interface class
public interface MyDialogListener {
void OnCloseDialog(Object obj); //you can put any object here
}
Implement the interface class in the Parent Fragment
public class ActionBarFragment extends Fragment implements MyDialogListener{
@Override
public void OnCloseDialog(Object obj) {
//Do you refresh
}
and then I add the listener inside the DialogFragment
public class SpecialDialogFragment extends DialogFragment {
MyDialogListener mListener;
public SpecialDialogFragment(MyDialogListener listener) {
this.mListener = listener;
}
@Override
public void onStop() {
super.onStop();
if(mListener!=null)
mListener.OnCloseDialog(null);
}
I just solved this in my project. What I have is an activity with a ListFragment. In that list fragment, when a particular item is clicked, I display a DatePickerFragment (a custom DialogFragment that displays a DatePickerDialog). When a date is selected, I want the ListFragment to be refreshed.
To achieve this, in the activity that hosts the ListFragment (and it also hosts the DatePickerFragment, as a matter of fact) I implemented a method that simply replaces the ListFragment with a new instance, like so:
public void criteriaChanged()
{
getFragmentManager().beginTransaction()
.replace(R.id.container, new FilterFragment())
.commit();
}
I call this method from the DatePickerFragment, from onDateSet():
FilterActivity fa = (FilterActivity) getActivity();
fa.criteriaChanged();
This does the trick for me.
One way to deal with this is to embed your DialogFragment within an Activity and display the activity as a Dialog, there's a tip in the following link that explains how:
http://developer.android.com/guide/topics/ui/dialogs.html
You can use this to update the underlying Fragment because when the Dialog (which is an Activity) is finished, onResume() will be called on the underlying fragment. Add code to update the state of the fragment in the onResume() method and that's all there is too it.
The top rated answers here have issues.
You cannot hold listeners as instance variables in a DialogFragment
, as they will not survive recreation, and you will left wondering why your callbacks 'magically' stop working.
You can read more about this here:
https://medium.com/@lukeneedham/listeners-in-dialogfragments-be636bd7f480
This article offers a couple of real solutions, of which my favourite is to use targetFragment
with a custom interface. For intercepting the dismiss, that looks like:
class MainFragment : Fragment(R.layout.fragment_main), DummyDialogCallback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
openDialogButton.setOnClickListener {
val dialog = DummyDialog()
dialog.setTargetFragment(this, DIALOG_DUMMY)
dialog.show(requireFragmentManager(), "DummyDialog")
}
}
override fun onDummyDialogClick() {
Toast.makeText(requireContext(), "Dummy click", Toast.LENGTH_SHORT).show()
}
companion object {
const val DIALOG_DUMMY = 1
}
}
class DummyDialog : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = inflater.inflate(R.layout.dialog_dummy, container, false)
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
val callback = targetFragment as? DummyDialogCallback
callback?.onDummyDialogClick()
}
}
interface DummyDialogCallback {
fun onDummyDialogClick()
}