Скользящая анимация плавающих ресурсов страницы Android + решение для скользящего мониторинга

1. Введение

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

        Однако ресурсы будут охватывать обычное содержимое.Если страница статична, ресурсы будут отображаться и скрываться при скольжении, так что содержимое процесса скольжения может быть полностью просмотрено потребителями в наибольшей степени.

2. Анализ

Распространенными являются recycleview или webview, оба из которых являются viewGroups. Нам нужно только отслеживать слайды страниц, но не все страницы знают о мониторинге слайдов. Или иметь возможность получить правильное скользящее состояние.

Но у всех представлений есть метод:

    public void setOnScrollChangeListener(OnScrollChangeListener l) {
        getListenerInfo().mOnScrollChangeListener = l;
    }
    public interface OnScrollChangeListener {
        /**
         * Called when the scroll position of a view changes.
         *
         * @param v The view whose scroll position has changed.
         * @param scrollX Current horizontal scroll origin.
         * @param scrollY Current vertical scroll origin.
         * @param oldScrollX Previous horizontal scroll origin.
         * @param oldScrollY Previous vertical scroll origin.
         */
        void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
    }

Это обеспечивается просмотром. Будь то представление или представление группы.

Мы можем судить о том, прокручивается ли текущий вид, отслеживая изменение координат вида в окне.

3. Решения

        С помощью анализа мы можем имитировать скользящий мониторинг, наблюдая за представлением. Время нормального скользящего обратного вызова может быть завершено в течение миллисекунд 150. Мы можем использовать таймер, чтобы получить время последнего скользящего и сравнить его с текущим временем, чтобы разницу во времени между скользящим и остановленным можно было отрегулировать в соответствии с бизнесом.

слайд-монитор

Демо:

class CountFlinerStatus {


    private  var time: Timer?=null

    private lateinit var scrollListener: ScrollStateCallback
    private var taskTime: Long = 0
    public fun scroll(scrollY: Int) {
        taskTime = System.currentTimeMillis()
        scrollListener?.let {
            it.onScrollState(true)
        }
        startTask()
    }

    public fun addScrollListener(scrollListener: ScrollStateCallback) {

        this.scrollListener=scrollListener
    }

    private fun startTask() {
        if (time == null) {
            time = Timer()
            time?.schedule(object : TimerTask() {
                override fun run() {

                    val newTime = System.currentTimeMillis()
                    if (newTime - taskTime > 200) {
                        //已停止

                        scrollListener?.let {
                            it.onScrollState(false)
                        }
                        cancelTask()
                    } else {
                        //还在滑动
                        scrollListener?.let {
                            it.onScrollState(true)
                        }
                    }

                }
            }, 1000,200)

        }

    }

    private fun cancelTask() {
        if (time != null) {
            time?.cancel();
            time = null;
        }
    }


    public interface ScrollStateCallback {
        public fun onScrollState(flying: Boolean)
    }

}

 Анимация:

Анимация выполняется в соответствии со скользящим обратным вызовом, который должен помнить начальную позицию представления (x или y).

class FlingerAnmationManager {

    companion object {

        val startMillTime: Long = 600

        fun startToLeft(image: View) {


            var with = image.measuredWidth

            val animator = ObjectAnimator()
            animator.setPropertyName("X");
            animator.setFloatValues(-(with * 0.5f))

            animator.setDuration(startMillTime)
            val action = AnimatorSet()
            action.play(animator)
            action.setTarget(image)

            action.start()

        }

        fun startToRight(image: View) {


            var with = image.measuredWidth

            val animator = ObjectAnimator()
            animator.setPropertyName("X");
            val disWidth = image.context.resources.displayMetrics.widthPixels
            animator.setFloatValues(disWidth - (with * 0.5f))

            animator.setDuration(startMillTime)
            val action = AnimatorSet()
            action.play(animator)
            action.setTarget(image)
            action.addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    super.onAnimationEnd(animation)


                }

                override fun onAnimationStart(animation: Animator) {
                    super.onAnimationStart(animation)

                }
            })
            action.start()

        }

        fun reBackLocation(image: View) {

            var mleft = if (image.tag != null) image.tag as Float else image.marginLeft
            val animator = ObjectAnimator()
            animator.setPropertyName("X");
            animator.setFloatValues(mleft?.toFloat())
            animator.setDuration(startMillTime)

            val action = AnimatorSet()
            action.play(animator)
            action.setTarget(image)


            action.start()
        }


    }
}

бой

первый шаг:

Инициализировать скользящий монитор

            manager = CountFlinerStatusManager()
            manager.addScrollListener(object : ScrollStateCallback {
                override fun onScrollState(flying: Boolean) {
                    if (!isAdded) return
                    runOnUiThread {
                        if (flying) {
                           onChildTouch(MotionEvent.ACTION_MOVE)
                        } else {
                            onChildTouch(MotionEvent.ACTION_UP)
                        }
                    }
                }
            })

Шаг второй:

Скользящий вид монитора

contentView.setOnScrollChangeListener(object : View.OnScrollChangeListener {
    override fun onScrollChange(
        v: View?,
        scrollX: Int,
        scrollY: Int,
        oldScrollX: Int,
        oldScrollY: Int
    ) {

        if (oldScrollY == 0 && contentRv.contentView.scrollState == 0)
            return
        manager.scroll(scrollY)
    }
})

третий шаг:

Обработка события скольжения.Перед обработкой скольжения обязательно запишите координаты вида, иначе при выполнении анимации возникнет ошибка

        view.postDelayed(object : Runnable {
            override fun run() {
                view.tag = view.x
            }
        }, 500)

обрабатывать анимацию

var viewFling :Boolean=false
    @Synchronized
    fun onChildTouch(action: Int) {

        when (action) {
            MotionEvent.ACTION_MOVE -> {
                if (viewFling == false) {
                    viewFling = true
                    FlingerAnmationManager.startToRight(view)
                }
            }
            MotionEvent.ACTION_UP -> {
                if (viewFling) {
                    viewFling = false
                    FlingerAnmationManager.reBackLocation(view)
                }
            }
        }

    }

4. Резюме

Благодаря приведенному выше анализу и реальному бою мы завершили обработку отслеживания перемещения ресурсов + анимацию.

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

Анимация должна сначала запомнить дефолтные координаты вида, иначе вы не сможете вернуться в исходное положение.

おすすめ

転載: blog.csdn.net/qq36246172/article/details/130561459