首页 > 解决方案 > 使用带有 replace() 的片段转换获得视觉“堆栈”行为

问题描述

我有一个由按钮和 ViewGroup 组成的活动,我想在其中堆叠片段。片段将仅显示数字 1、2、3 ......并且,我希望新片段的视觉行为“滑动或淡入”,同时覆盖下面编号较低的片段,该片段应该“保持原位”。

当使用后退按钮从堆栈中弹出片段时,编号较高的片段应该“滑动或淡出”,同时显示编号较低的片段,就好像它一直在下方一样。

我想将 Transition API (android.transition.*) 与片段 setEnterTransition / setExitTransition 方法一起使用,以便以后可以添加共享元素转换。

在此处输入图像描述

在视频中,我强制“退出”过渡实际移动(向上滑动)到很容易看到,由于某种原因,它呈现在我的新片段动画的顶部。

这是我的主要问题和问题:如何使被覆盖的片段呈现我正在制作动画的新片段下方?

顺便说一句,我发现让编号较低的片段在被覆盖时“保持原状”的唯一方法是破解淡入淡出过渡以实际返回一个基本上对视图“什么都不做”的动画师。

我花了几个小时在这上面,我开始认为我可能在概念上有些错误,因为在我看来,当“堆叠”片段时,我的要求似乎是最“自然”的事情,但同时又几乎不可能达到。

我的代码的相关部分:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.button).apply {
            setOnClickListener {
                stackMagicFragment()
            }
        }

        supportFragmentManager.beginTransaction()
                .replace(R.id.injectionPoint, ColorFragment())
                .commit()
    }

    private fun stackMagicFragment() {
        supportFragmentManager.beginTransaction()
                .setReorderingAllowed(true)
                .replace(R.id.injectionPoint, ColorFragment().apply { character = 'a' + supportFragmentManager.backStackEntryCount + 1 })
                .addToBackStack(null)
                .commit()
    }
}

class ColorFragment : Fragment() {

    companion object {
        private val rnd = Random()
    }

    var character: Char = 'a'

    private val ourColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enterTransition = Slide(Gravity.END).apply { duration = 1000 }
        exitTransition = Slide(Gravity.TOP).apply { duration = 1000 }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return FrameLayout(requireContext()).apply {
            setBackgroundColor(ourColor)
            addView(TextView(requireContext()).apply {
                text = getOurText()
                textSize = 200.toFloat()
                gravity = Gravity.CENTER
            })
        }
    }

    private fun getOurText(): String {
        return "" + character
    }
}

标签: androidkotlintransitionandroid-transitionsshared-element-transition

解决方案


推荐阅读