Solution 1 :
AlertDialog automatically dismisses the Dialog (and hence, removes your DialogFragment
) when the callback you add to setPositiveButton
is fired. Because you’re doing work asynchronously, your databaseSavingCompleted
method is called after the DialogFragment is destroyed, detached from the FragmentManager, and removed from the NavController – you’re leaking a reference to your DialogFragment (as it would otherwise be garbage collected).
Therefore when NavHostFragment.findNavController(this)
fires, all hooks that would let it access the NavController
are already cleaned up.
If you don’t want your button to immediately dismiss the dialog, you need to pass in null
to setPositiveButton()
and instead get a reference to the button after the dialog has been created by calling its getButton()
API and manually setting an OnClickListener
that would kick off your AsyncTask
(and disable the button to prevent it from being clicked more than once).
Problem :
Disclaimer: I’ve checked the documentation and since 2.1.0
the navigation components has supported Dialog Fragments. (https://developer.android.com/jetpack/androidx/releases/navigation#2.1.0)
Error That I’m Getting
I’m getting this error when trying to go from a DialogFragment
to my Start Destination
:
java.lang.IllegalStateException: Fragment PostDistressDialog{829f5d1} (bbbc4926-684b-491b-9772-e0f0ffebe0af)} not associated with a fragment manager.
PostDistressDialog
is a DialogFragment
called from JournalEntryFragment
(can be seen in map below) using the navigation component. PostDistressDialog
is not an inner class of JournalEntryFragment
. It is in a class of its own extending DialogFragment
Picture of my Navigation Graph
Function Calling NavController
public class PostDistressDialog extends DialogFragment implements ISaveDatabase {
...
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
if (getArguments()!=null) {
...
// Set up the Alert Dialog
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setTitle(R.string.distressed_levels);
alertDialog.setMessage(R.string.distressed_how_feel_post);
// Inflate and set the layout for the dialog
View layout = View.inflate(getActivity(), R.layout.dialog_seekbar, null);
alertDialog.setView(layout);
....
// Add okay button
alertDialog.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Save post distress value in Journal Entry
mJournalEntry.setPostDistress(mTempDistressValue);
// Save to Journal Entry to database
// Check if journal entry empty
if(isJournalEntryEmpty(mJournalEntry)){
...
}
else{
// Give title if empty
if(mJournalEntry.getTitle().isEmpty()) {
....
// Save to database
new SaveDatabase(getContext(),PostDistressDialog.this).execute(mJournalEntry);
}
// Go to main menu
}
});
return alertDialog.create();
}
return null;
}
...
@Override
public void databaseSavingCompleted(){
NavHostFragment.findNavController(this).navigate(PostDistressDialogDirections.postDistressDialogToJournalListAction());
}
}
Where this
is public class PostDistressDialog extends DialogFragment
Dialog in my Navigation XML File
<dialog
android_id="@+id/postDistressDialog"
android_name="com.dgrullon.cbtjourney.dialogs.PostDistressDialog"
android_label="PostDistressDialog" >
<argument
android_name="postDistressDialogArguments"
app_argType="com.dgrullon.cbtjourney.pojo.JournalEntries"/>
<action
android_id="@+id/postDistressDialog_to_journalListAction"
app_destination="@id/journalList"
app_popUpTo="@id/journalList"
app_popUpToInclusive="true" />
</dialog>
Comments
Comment posted by ianhanniballake
“not associated with a fragment manager” means your Fragment is no longer attached to the FragmentManager. Where are you calling
Comment posted by Rayaarito
Thanks for the quick reply @ianhanniballake. I edited my answer to show more of my