#android #kotlin #android-animation
#Android #kotlin #android-анимация
Вопрос:
В настоящее время я пытаюсь изменить matchConstraintPercentWidth
значение представления с 2 на 0, используя Animation()
при запуске моей деятельности (в методе onWindowFocusChanged()
, чтобы убедиться, что все представления были нарисованы правильно). Проблема в том, что анимация заканчивается мгновенно (и у этого представления теперь есть новые параметры — похоже, что продолжительность анимации равна 0 мс), независимо от продолжительности, которую я установил… Вот мой код (на Kotlin) :
override fun onWindowFocusChanged(hasFocus: Boolean) {
if (hasFocus) {
val gradient = findViewById<ImageView>(R.id.black_gradient)
val animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
val params = gradient.layoutParams as ConstraintLayout.LayoutParams
params.matchConstraintPercentWidth = 0f
gradient.layoutParams = params
}
}
animation.duration = 2000L // in ms
gradient.startAnimation(animation) //also tried animation.start() without effect
//animation.hasStarted() is always false here
}
}
Любая помощь приветствуется 😉
Ответ №1:
Этот applyTransformation
метод предназначен для вычисления текущего состояния анимации на основе interpolatedTime
(что находится между 0.0
и 1.0
). Вы просто устанавливаете значение ограничения равным 0, поэтому на самом деле оно не изменяет значение с течением времени и ничего не анимирует.
Честно говоря, вы, вероятно, не захотите ничего из этого трогать, если сможете, в Android есть несколько вспомогательных классов, которые абстрагируют многие детали, так что вы можете просто анимировать вещь.ValueAnimator, вероятно, хороший крик, вы могли бы просто сделать
ValueAnimator.ofFloat(0f, 100f).apply {
addUpdateListener { anim ->
val params = (gradient.layoutParams as ConstraintLayout.LayoutParams)
params.matchConstraintPercentWidth = anim.animatedValue as Float
}
duration = 1000
start()
}
и это должно быть эквивалентно тому, что вы делаете. ObjectAnimator
По этой ссылке тоже есть ссылка, но для этого требуется метод установки, а для этого параметра макета его нет (у ConstraintProperties есть некоторые, но не для этого, насколько я вижу)
Комментарии:
1. Спасибо! Это работает (но нам абсолютно необходимо обновить и применить процентную ширину, используя
gradient.layoutParams = params
в концеaddUpdateListener()
^^2. Ах, хорошо, да, я просто обрезал его, но я действительно ничего не знаю об анимации параметров макета! Кроме того, если вы еще не видели
MotionLayout
, об этом может быть полезно знать, посмотрите, соответствует ли это тому, что вы делаете (это также, по-видимому, новая мода) developer.android.com/training/constraint-layout/motionlayout
Ответ №2:
Для меня код выглядит нормально, попробуйте удалить условие hasFocus , потому что могут быть некоторые представления, которые могут попасть в фокус до того, как эта конкретная вещь, которую вы должны сделать для диагностики, это
-
попробуйте войти
hasFocus
, если он не получает фокус, затем измените код, как показано ниже, также просто совет, который вы всегда должны инициализировать представления вне обратных вызовов.override fun onWindowFocusChanged(hasFocus: Boolean) { val gradient = findViewById<ImageView>(R.id.black_gradient) val animation = object : Animation() { override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { val params = gradient.layoutParams as ConstraintLayout.LayoutParams params.matchConstraintPercentWidth = 0f gradient.layoutParams = params } } animation.duration = 2000L // in ms gradient.startAnimation(animation) //also tried animation.start() without effect //animation.hasStarted() is always false here }