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. Резюме
Благодаря приведенному выше анализу и реальному бою мы завершили обработку отслеживания перемещения ресурсов + анимацию.
Суть здесь в том, чтобы настроить собственный механизм мониторинга скольжения, это, по сути, половина успеха, а остальное — отладка анимации.
Анимация должна сначала запомнить дефолтные координаты вида, иначе вы не сможете вернуться в исходное положение.