I have FragmentA, FragmentB and DialogFragment(BottomDialogFragment). I I abbreviated them as A,B and D
D will be shown after the button in A is clicked. It means A -> D
B will be shown after the button in D is clicked. It means D -> B
I config them in navigation.xml
<fragment
android:id="@+id/A"
android:name="com.example.A">
<action
android:id="@+id/A_D"
app:destination="@id/D" />
</fragment>
<dialog
android:id="@+id/D"
android:name="com.example.D">
<action
android:id="@+id/D_B"
app:destination="@id/B" />
</dialog>
<fragment
android:id="@+id/B"
android:name="com.example.B">
</fragment>
Now when I click the button in A, the fragment will jump to D.
Then I click the button in D, the fragment will jump to B.
But when I pop the navigation stack in B, it will back to A, and the D doesn't show.
What should I do? I want the D still exists on the surface of A.
What should I do? I want the D still exists on the surface of A.
So far, this is not possible, because dialogs are handled in a separate window than the activities/fragments; and therefore their back stack is handled differently And this is because Dialog
implements the FloatingWindow interface.
Check this answer for more clarification.
But to answer your question, there are two approaches in mind:
B
to a DailogFragment
, and in this case both B
& D
are dialogs and therefore when you popup the stack to back from B
to D
, you'll still see D
showing.B
to D
, and when if so, you re-show D
.Actually, approach 2 isn't that good, because it doesn't keep D
in the back stack while you go from D
to B
; it's just a workaround; also the user would see the dialog transitioning/fade animation while it returns from B
to D
; so it's not natural at all. So, here only approach 1 will be discussed.
Pros:
Cons:
DialogFragment B
has a limited window than the normal fragment/activity.B
is no longer a normal fragment, but a DialogFragment
, so you might encounter some other limitations.To solve the limited window of B
, you can use the below theme:
<style name="DialogTheme" parent="Theme.MyApp">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowIsFloating">false</item>
</style>
Where Theme.MyApp
is your app's theme.
And apply it to B
using getTheme()
:
class FragmentB : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return layoutInflater.inflate(R.layout.fragment_b, container, false)
}
override fun getTheme(): Int = R.style.DialogTheme
}
Also you need to change B
in the navigation graph to a dialog:
<dialog
android:id="@+id/B"
android:name="com.example.B">
</dialog>
Preview: