DialogFragment and onDismiss

前端 未结 8 1976
迷失自我
迷失自我 2020-11-27 16:14

I am using a DialogFragment, which I am showing like this from an Activity:

DialogFragmentImage dialog = DialogFragmentImage.newIns         


        
8条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-27 16:19

    If you don't like the solution of @yaroslav-mytkalyk, in which the fragment needs to cast the activity / parent fragment, here's another one:

    Here's the idea:

    1. Expose a listener in your fragment, DialogFragmentImage.
    2. Implement the listener in your activity and pass it to the fragment when creating it. Make sure to use a tag as well in order to be able to find the fragment later (read below).
    3. In onStop(), remove the listener in order not to leak the activity if it's destroyed. This will happen when the screen is rotated, as the activity will be re-created.
    4. In onResume(), check if the fragment exists and if yes, re-add the listener.

    Expose a listener from your fragment:

    class MyFragment extends DialogFragment {
    
        public interface OnDismissListener {
            void dismissed();
        }
    
        @Nullable
        private OnDismissListener onDismissListener;
    
        public void setOnDismissListener(@Nullable OnDismissListener onDismissListener) {
            this.onDismissListener = onDismissListener;
        }
    
        /*
        If you are calling dismiss() or dismissAllowingStateLoss() manually,
        don't forget to call:
        if (onDismissListener != null) {
            onDismissListener.dismissed();
        }
    
        Otherwise, override them and call it there.
        */
    }
    

    And this is how your activity should look like:

    class MyActivity extends AppCompatActivity {
    
        private static final String MY_FRAGMENT_TAG = "my_fragment";
    
        private MyFragment.OnDismissListener myFragmentListener = () -> {
    
            // ...
        };
    
        /**
         * Shows the fragment. Note that:
         * 1. We pass a tag to `show()`.
         * 2. We set the listener on the fragment.
         */
        private void showFragment() {
    
            MyFragment fragment = new MyFragment();
            fragment.show(getSupportFragmentManager(), MY_FRAGMENT_TAG);
            fragment.setOnDismissListener(myFragmentListener);
        }
    
        @Override
        protected void onStart() {
    
            super.onStart();
    
            // Restore the listener that we may have removed in `onStop()`.
            @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
            if (myFragment != null) {
                myFragment.setOnDismissListener(myFragmentListener);
            }
        }
    
        @Override
        protected void onStop() {
    
            // If the fragment is currently shown, remove the listener so that the activity is not leaked when e.g. the screen is rotated and it's re-created.
            @Nullable MyFragment myFragment =  (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
            if (myFragment != null) {
                myFragment.setOnDismissListener(null);
            }
    
            super.onStop();
        }
    }
    

提交回复
热议问题