Получение визуального поведения стека с использованием переходов фрагментов с replace()

У меня есть активность, состоящая из кнопки и ViewGroup, в которой я хочу складывать фрагменты. Фрагменты будут просто отображать номер 1, 2, 3 ... и я хочу, чтобы визуальное поведение нового фрагмента «скользило или исчезало», закрывая фрагмент с меньшим номером ниже, который должен «оставаться на месте».

При извлечении фрагментов из стека с помощью кнопки «Назад» фрагмент с более высоким номером должен «скользить или исчезать», открывая фрагмент с более низким номером, как если бы он все время находился внизу.

Я хочу использовать API-интерфейсы Transition (android.transition.*) вместе с методами фрагментов setEnterTransition/setExitTransition, чтобы позже я мог добавить общие переходы элементов.

введите здесь описание изображения

В видео я заставляю переход «выход» фактически двигаться (скользить вверх), чтобы было легко увидеть, что по какой-то причине он отображается поверх моей анимации нового фрагмента.

Это моя основная проблема и вопрос: как я могу заставить покрываемый фрагмент визуализировать ниже мой новый фрагмент, в котором анимируется?

Кроме того, кстати, единственный способ, которым я обнаружил, чтобы фрагмент с меньшим номером «оставался на месте», пока он закрывается, — это взломать переход Fade, чтобы фактически вернуть Animator, который в основном «ничего» не делает для вида.

Я потратил на это несколько часов и начинаю думать, что у меня может быть что-то концептуально не так, так как мои требования кажутся мне наиболее «естественными», которых можно ожидать при «укладке» фрагментов, но в то же время были довольно невыполнимыми. достигать.

Соответствующие части моего кода:

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
    }
}

person droid256    schedule 14.12.2018    source источник