У меня есть анимация, которая по существу сортирует пронумерованные шары, переводя значение X. В первый раз он работает отлично, но когда я генерирую новые числа и пытаюсь снова отсортировать, он не работает как задумано.
Первый гиф это работает нормально.
https://giphy.com/gifs/igyw5gvPtbmEOZqoBP
Здесь я нажимаю кнопку сортировки, и шары сортируются правильно.
В следующем gif я генерирую новое число, а затем пытаюсь отсортировать, но, как вы можете видеть, я получаю странное поведение.
http://www.giphy.com/gifs/kAuH2ZnnNCRX6bPKto
Это почти как если бы он использовал старое значение X для перевода.
Вот метод сортировки, который запускает аниматон
private fun sort() {
val animator = AnimatorSet()
val sorted = balls.sortedBy { x -> x.value }
sorted.forEachIndexed { index, ball ->
if (balls[index] == ball) {
return@forEachIndexed
}
val occupyingBall = balls[index]
val startingPos = balls.indexOf(ball)
// move starting ball to occupying ball
val occupyingRect = calculateRectOnScreen(occupyingBall)
val startingRect = calculateRectOnScreen(ball)
val move = getMoveAnimation(ball, startingPos, balls.indexOf(occupyingBall), occupyingRect, startingRect)
animator.play(move)
animator.start()
}
balls.clear()
balls.addAll(sorted)
}
Вот метод getMoveAnimation
, который создает аниматор объектов.
private fun getMoveAnimation(view: View, startingIndex: Int, finishingIndex: Int, rect1: RectF, rect2: RectF): ObjectAnimator {
val distance = if (startingIndex > finishingIndex) {
// Move left
-Math.abs(rect1.right - rect2.right)
} else {
// Move right
Math.abs(rect1.right - rect2.right)
}
return ObjectAnimator.ofFloat(view, "translationX", distance)
}
А вот calculateRectOnScreen
метод расчета расстояния между видами
private fun calculateRectOnScreen(view: View): RectF {
val location = IntArray(2)
view.getLocationOnScreen(location)
return RectF(location[0].toFloat(), location[1].toFloat(), (location[0] + view.measuredWidth).toFloat(), (location[1] + view.measuredHeight).toFloat())
}