Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to replace one full-screen dialog fragment with another without showing parent activity?

I have an Activity that uses a single custom DialogFragment class. Its appearance is data driven, so it can look fairly different from invocation to invocation.

It is "full screen", i.e.

setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme);

In response to the result of a network call I dismiss() the currently showing instance (if there is one) and show() a new one:

final CustomDialogFragment dialog = (CustomDialogFragment) getSupportFragmentManager().findFragmentByTag(DIALOG_TAG_CUSTOM);
if (dialog != null)
    dialog.dismiss();
final CustomDialogFragment newdialog = new CustomDialogFragment();
// configure some stuff on the new fragment that influences its appearance
newdialog.show();

Here is my issue: when this block of code runs, between the point at which the existing Fragment disappears and the new one becomes visible I can briefly see the underlying Activity. I'd like to avoid this somehow.

My first thought was to dismiss the existing fragment inside the onResume() method of the new fragment. That is, to delay the "dismiss()" call as long as possible in hopes that the new fragment would already be visible (obscuring the previous one) before the previous one was dismissed. But this had no effect.

Another option I'm considering is to make the fragment "reconfigurable" so that I can "push in" new data and trigger it to redraw all its views to match the new data. In this solution, I would simply reconfigure the existing fragment (if there is one) instead of dismissing it and showing a new one.

My question: is there an easier and/or more straightforward way to get around this temporary "peek" at the underlying Activity when dismissing one full-screen DialogFragment and showing another?

like image 945
jph Avatar asked Aug 26 '14 22:08

jph


1 Answers

Depending on what your activity and full-screen fragments look like, a few options come to mind.

  1. Following your own first thought: try scheduling the dismissal of the first data-driven fragment in the second by posting it to the root view's handler. That is:

    @Override
    public View onCreateView (LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
        View root = ... // inflate view
        root.post(new Runnable() {
             @Override public void run() {
                 // create & commit fragment transaction 
                 // to remove first fragment here
                 }
             };
        return root;
    }
    

    This should ensure that the dismissal doesn't happen until after the second fragment has become visible. If you build a custom dialog using onCreateDialog(Bundle savedInstanceState), make sure you post to the view you inflate there in stead.

  2. Instantiate both full-screen fragments and use show() and hide() transactions to switch between them (as opposed to actual replace() or remove()-and-add() transactions). These operations should be a lot faster to toggle between two fragments, as both will have already been more or less fully initialised upon executing the transaction (in other words: less delay when 'switching'). This will yield a small performance hit, but potentially negligible. It's noy ideal with data-driven fragments, especially if you supply the data using an arguments bundle, but not too hard to overcome by creating some setters.

  3. If the two full-screen fragments have an identical background (i.e. a simple colour), then you could give the activity's background the same colour. When the fragments then get swapped out, the visual result will be a momentarily blank screen, but less intrusive, as only the content changes (because the background will stay the same).

    Now, if the activity is not merely a container, but displays its own content, you can still achieve the same as above by introducing a third (full-screen, opaque) fragment as an extra layer to obscure the underlying activity while switching between the full-screen fragments. Just leave the obscuring layer in place when you do so, and dismiss it when returning to the activity's content.

    If the activity and fragments have a very richly and differently decorated background, then this last option may not be ideal.

like image 154
MH. Avatar answered Nov 15 '22 01:11

MH.