Я использую макет движения в своей основной деятельности. Работает исправно. Однако, когда я перехожу к другим действиям и возвращаюсь к своему основному действию, иногда действие сбрасывается, и макет находится в начальном состоянии. Как мне этого избежать? Помимо этого, у меня также есть еще один вопрос о макете движения, который я задал здесь а>
Сброс макета движения при переходе между занятиями
Ответы (5)
Что я сделал, так это добавил поле, логическое поле, чтобы быть конкретным и использовать жизненный цикл для его обработки.
private var hasMotionScrolled = false
override fun onResume() {
super.onResume()
if (hasMotionScrolled) motionLayout.progress = MOTION_TRANSITION_COMPLETED
}
override fun onPause() {
super.onPause()
hasMotionScrolled = motionLayout.progress > MOTION_TRANSITION_INITIAL
}
companion object {
private const val MOTION_TRANSITION_COMPLETED = 1F
private const val MOTION_TRANSITION_INITIAL = 0F
}
Итак, в моем случае макет движения выполняет анимацию, связанную с прокруткой. Если это не ваш случай, возможно, вы можете использовать непосредственно motionLayout.progress
. Моя проблема с использованием progress
напрямую заключалась в том, что промежуточные состояния делали бы другие элементы невидимыми при переходе назад, поэтому реализован логический флаг «все или ничего».
Я не считаю это чистым решением, флаг - это всегда то, что означает, что что-то еще могло быть лучше, если вы найдете что-то официальное, дайте мне знать в комментариях.
onSaveInstanceState
- person fklappan; 16.07.2020
Вы должны сохранить / восстановить прогресс вашего MotionLayout:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putFloat("progress", motionLayout.progress)
}
override fun onCreate(savedInstanceState: Bundle?) {
...
if (savedInstanceState != null)
motionLayout.progress = savedInstanceState.getFloat("progress", 0f)
...
}
Вы можете добавить слушателя перехода в макет движения и сохранить флаг, когда переход будет завершен. Впоследствии, когда действие будет воссоздано, вы можете прочитать этот флаг и использовать что-то вроде:
motionLayout.setState(R.id.end, ConstraintSet.WRAP_CONTENT, ConstraintSet.WRAP_CONTENT)
Где R.id.end - это идентификатор из свойства constraintSetEnd.
Вот как я это делаю с Fragment
Создайте переменную экземпляра в своем классе Fragment
:
var motionProgress = 0f // 0f being initial state
В вашей функции onViewCreated
присвойте текущее значение макету:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.motionLayout.progress = motionProgress
}
Наконец, при переходе от Fragment
обновите значение motionProgress
в функции onPause
:
override fun onPause() {
super.onPause()
motionProgress = binding.motionLayout.progress
}