package com.gh.common.view import android.content.Context import android.os.Build import android.util.AttributeSet import android.view.MotionEvent import android.widget.LinearLayout import androidx.annotation.Nullable import androidx.core.view.children import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent import androidx.recyclerview.widget.RecyclerView import java.lang.ref.WeakReference import java.util.* class AutoScrollRecyclerViewContainerView(context: Context, @Nullable attrs: AttributeSet?) : LinearLayout(context, attrs), LifecycleObserver { var autoScrollTask: AutoScrollTask? private var mIsScrolling = false private var mIsScrollable = false private var mOnItemTouchListener: RecyclerView.OnItemTouchListener? = null init { autoScrollTask = AutoScrollTask(this) } override fun onAttachedToWindow() { super.onAttachedToWindow() if (mOnItemTouchListener == null) { mOnItemTouchListener = object : RecyclerView.OnItemTouchListener { override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {} override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent) = rv.scrollState == RecyclerView.SCROLL_STATE_DRAGGING override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} } } for (child in children) { if (child is RecyclerView) { child.removeOnItemTouchListener(mOnItemTouchListener!!) child.addOnItemTouchListener(mOnItemTouchListener!!) } } resumeScrolling() } override fun onDetachedFromWindow() { super.onDetachedFromWindow() pauseScrolling() } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun resumeScrolling() { if (mIsScrolling) return if (mIsScrolling) pauseScrolling() mIsScrollable = true mIsScrolling = true postDelayed(autoScrollTask, AUTO_SCROLL_INTERVAL) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun pauseScrolling() { mIsScrolling = false removeCallbacks(autoScrollTask) } fun setLifeCycleOwner(lifeCycleOwner: Lifecycle) { lifeCycleOwner.addObserver(this) } companion object { private const val AUTO_SCROLL_INTERVAL: Long = 10 } class AutoScrollTask(reference: AutoScrollRecyclerViewContainerView?) : Runnable { private val mReference: WeakReference? private val mScrollSlop = if (Build.MODEL.toLowerCase(Locale.getDefault()) == "mumu") 1 else 2 init { mReference = WeakReference(reference) } override fun run() { val containerView: AutoScrollRecyclerViewContainerView? = mReference?.get() if (containerView != null && containerView.mIsScrolling && containerView.mIsScrollable) { for (child in containerView.children) { if (child is RecyclerView) { child.scrollBy(mScrollSlop, mScrollSlop) } } containerView.postDelayed(containerView.autoScrollTask, AUTO_SCROLL_INTERVAL) } } } }