morristech
5/14/2019 - 11:09 PM

DialogFragment which can have hide animations

DialogFragment which can have hide animations

/**
 * Dialog Fragment with hide animations
 */
class AnimatingDialogFragment : DialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(DialogFragment.STYLE_NO_FRAME, R.style.TvTheme_Dialog)
    }

    fun dismissImmediately() {
        super.dismiss()
    }

    /**
     * So the problem is that DialogFragment animations do not work.
     * The fragment manager does not run the animations because it is not a true fragment,
     * and it is not attached to any container.
     * The DialogFragment itself does not execute the window animations (it hides the window immediately).
     * So what I do is that I intercept the dismissal of the view and animate it before executing the true dismiss()
     */
    override fun dismiss() {
        val view = view
        if (view != null) {
            val animation = AnimationUtils.loadAnimation(view.context, R.anim.dialog_fade_out)
            animation.setAnimationListener(object : Animation.AnimationListener {
                override fun onAnimationRepeat(animation: Animation?) {
                    // Unused
                }

                override fun onAnimationEnd(animation: Animation?) {
                    super@BaseDialogFragment.dismiss()
                }

                override fun onAnimationStart(animation: Animation?) {
                    // Unused
                }
            })
            view.startAnimation(animation)
        } else {
            super.dismiss()
        }
    }

    /**
     * Continuing on the logic below, we need to call our dismiss() method on the back button.
     */
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)
        dialog.setOnKeyListener(object : DialogInterface.OnKeyListener {

            override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    if (event.action == KeyEvent.ACTION_UP) {
                        dismiss()
                    }
                    return true
                }
                return false
            }
        })
        return dialog
    }
}