Nested fragments transitioning incorrectly

倖福魔咒の 提交于 2019-11-29 03:08:59

I think I've found a way to solve this using Fragment#onCreateAnimator. A gif of the transition can be viewed here: https://imgur.com/94AvrW4.

I made a PR for testing, so far it's working as I expect and surviving configuration changes and supporting the back button. Here is the link https://github.com/zafrani/NestedFragmentTransitions/pull/1/files#diff-c120dd82b93c862b01c2548bdcafcb20R25

The BaseFragment for both the Parent and Child fragments is doing this for onCreateAnimator()

override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator {
    if (isConfigChange) {
        resetStates()
        return nothingAnim()
    }

    if (parentFragment is ParentFragment) {
        if ((parentFragment as BaseFragment).isPopping) {
            return nothingAnim()
        }
    }

    if (parentFragment != null && parentFragment.isRemoving) {
        return nothingAnim()
    }

    if (enter) {
        if (isPopping) {
            resetStates()
            return pushAnim()
        }
        if (isSuppressing) {
            resetStates()
            return nothingAnim()
        }
        return enterAnim()
    }

    if (isPopping) {
        resetStates()
        return popAnim()
    }

    if (isSuppressing) {
        resetStates()
        return nothingAnim()
    }

    return exitAnim()
}

The booleans are being set in different scenarios that are easier to see in the PR.

The animation functions are:

private fun enterAnim(): Animator { 
        return AnimatorInflater.loadAnimator(activity, R.animator.fragment_enter)
    }

    private fun exitAnim(): Animator { 
        return AnimatorInflater.loadAnimator(activity, R.animator.fragment_exit)
    }

    private fun pushAnim(): Animator { 
        return AnimatorInflater.loadAnimator(activity, R.animator.fragment_push)
    }

    private fun popAnim(): Animator { 
        return AnimatorInflater.loadAnimator(activity, R.animator.fragment_pop)
    }

    private fun nothingAnim(): Animator { 
        return AnimatorInflater.loadAnimator(activity, R.animator.fragment_nothing)
    }

Will leave the question open incase someone finds a better way.

You are getting so wired result, cause you are using exit animations for your Fragment. Basically, we have such issues with Fragment animation every time, and finally moved from source Fragment animation, to using own, each time we preforming transition.

1) To verify this behavior, you can just remove exit animation for fragment, and everything will be ok. In most cases it should be enough, cause exit animation very specific and used only for single fragment managing (not in you case, with childs)

getFragmentManager().beginTransaction()
                .setCustomAnimations(R.animator.enter_anim_frag1,
                                     0,
                                     R.animator.enter_anim_frag2,
                                     0)
                .replace(xxx, Xxx1, Xxx2)
                .addToBackStack(null)
                .commit()

2) Another option, which might suite, it's think about application structure and try to avoid replace Fragment with animation. In case you need replace, don't use animation, and you can add any animation(including both enter and exit), but only with adding.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!