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

戏子无情 提交于 2019-12-05 10:10:46
MH.

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.

It might be worth trying to use the FragmentManager to execute both the removal of the first DialogFragment and the addition of the second in one transaction. I have an application which frequently swaps overlaying fragments out, and using this method I never notice the background fragment being revealed.

FragmentManger fm = getSupportFragmentManager();
FragmentTransaction trans = fm.beginTransaction().remove(dialog);
newDialog.show(trans, "insert_tag_here_if_you_want");
trans.commit();

Keep in mind I usually use this with ordinary fragments within containers, but again it's worth trying.

Apply fade out animation to the first dialog. As a result, when the first dialog is dismissed and second dialog is shown, second dialog will appear immediately on top of first dialog and the first dialog will fade out slowly in the background. There by the activity window does not appear in this transition.

Define an alpha animation : res/anim/dialog_fade_out.xml

<?xml version="1.0" encoding="utf-8"?>
<alpha  xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="400">
</alpha>

Define window animation style : res/style/custom_dialog_style.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="dialog_fade_out_animation" >
        <item name="android:windowExitAnimation">@anim/dialog_fade_out</item>
    </style>
</resources>

Since DialogFragment manages Dialog instance, apply the animation to the window of dialog instance. Do it in onStart method, by then dialog instance will be created.

public static class FirstDialogFragment extends DialogFragment {
    public void onStart() {
        super.onStart();

        Dialog d = this.getDialog();
        if(d != null)
            d.getWindow().setWindowAnimations(R.style.dialog_fade_out_animation);
    }
}

I Did Somthing Like this in monoandroid (Xamarin)

public override void OnResume()

    {
        // Auto size the dialog based on it's contents
        Dialog.Window.SetLayout(LinearLayout.LayoutParams.MatchParent,           LinearLayout.LayoutParams.WrapContent);
        // Make sure there is no background behind our view
        //Dialog.Window.SetBackgroundDrawableResource(Resource.Color.transparent_black);
        Dialog.Window.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));
        // Disable standard dialog styling/frame/theme: our custom view should create full UI
        SetStyle(Android.Support.V4.App.DialogFragment.StyleNoFrame, Android.Resource.Style.Theme);
        base.OnResume();
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!