Задержка событий onFocusChanged при длительной прокрутке - PullRequest
0 голосов
/ 23 апреля 2020

ПРИМЕЧАНИЕ: Я работаю над приложением AndroidTV, поэтому я использую фокус-навигацию и дистанционное управление.

У меня есть утилита-ретранслятор Просмотр элементов, где я делаю анимацию в onFocusChange каждого элемента , Поэтому, когда вы go просматриваете список с помощью кнопок со стрелками, он подсвечивает каждый элемент с помощью анимации:

 override fun onFocusChange(v: View?, focused: Boolean) {

    val card = rowItemView.card
    val title = rowItemView.title

    val smallAnimation = rowItemView.viewModel.useSmallScaleAnimation


    card.pivotX = when  {
        smallAnimation && position != 0->  card.width.toFloat() / 2.0f
        else -> 0f
    }

    card.pivotY = card.height.toFloat() / 2.0f

    if (focused) {
        rowItemView.viewModel.setIsFocused(focused)
        card.doTheAnimation(
            titleView = title,
            scale = if (smallAnimation) 1.5f else 1.2f,
            elevation = 8.0f,
            destinationAlpha = 1.0f
        )
        card.cardElevation = rowItemView.context.resources.getDimensionPixelSize(R.dimen.small_card_elevation).toFloat()
    }
    else {
        card.doTheAnimation(
            titleView = title,
            scale = 1.0f,
            elevation = 0.0f,
            destinationAlpha = 0.0f,
            onAnimationEnd = { rowItemView.viewModel.setIsFocused(focused) }
        )
        card.cardElevation = 0f
    }
}

private fun View.doTheAnimation(
    titleView: View?,
    scale: Float,
    elevation: Float,
    destinationAlpha: Float,
    onAnimationEnd: () -> Unit = {}
) {
    val bannerX = ObjectAnimator.ofFloat(this, View.SCALE_X, scale)
    val bannerY = ObjectAnimator.ofFloat(this, View.SCALE_Y, scale)
    val bannerZ = ObjectAnimator.ofFloat(this, View.TRANSLATION_Z, elevation)

    val animSet = AnimatorSet()
    if (titleView != null) {
        val titleAlpha = ObjectAnimator.ofFloat<View>(
            titleView,
            View.ALPHA,
            destinationAlpha
        )
        animSet.playTogether(bannerX, bannerY, bannerZ, titleAlpha)
    } else {
        animSet.playTogether(bannerX, bannerY, bannerZ)
    }
    animSet.duration = 150L
    animSet.addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationStart(animation: Animator) {
            titleView?.visibility = View.VISIBLE
        }

        override fun onAnimationEnd(animation: Animator) {
            if (titleView?.alpha == 0.0f) {
                titleView.visibility = View.GONE
            } else {
                titleView?.visibility = View.VISIBLE
            }
            onAnimationEnd.invoke()
        }
    })

    // `Handler().post` is attempt to speed up animation a little -> might be removed in future if nop benefit can be experienced
    Handler().post{
        animSet.start()
    }
}

Но вы также можете удерживать кнопку со стрелкой на пульте дистанционного управления, а затем выполняется быстрая прокрутка список. Проблема в том, что в этом случае анимация пытается запустить для каждого отдельного элемента быструю прокрутку, и она не выглядит хорошо. Выглядит глючно и разбито.

Возможно ли как-нибудь запустить анимацию только для действительно сфокусированных предметов ? Таким образом, когда вы нажимаете стрелки, он запускается для каждого элемента, но когда вы удерживаете стрелку, он запускается только для элемента, на котором вы остановились?

...