在我的应用程序中,有一个包含产品图像的viewPager,我创建了每3秒自动滑动一次图像的逻辑。显示一个图像,如果用户触摸屏幕,它应该停止滑动,当它到达最终图像时,滑块会再次从第一个图像重新启动,以此类推,问题是有时滑块挂起并继续更快地从第一个图像移动到最后一个图像,
下面的GIF描述了这个问题
完整的代码
companion object {
private const val DELAY_TIME: Long = 3000
private const val PERIOD_TIME: Long = 3000
private var currentPage = 0
}
private var timer: Timer? = null
private var sliderHandler: Handler? = null
private var update: Runnable? = null
private lateinit var onPageChangeCallback: OnPageChangeCallback
private var arrangedList = arrayListOf<SliderModel>()
@SuppressLint("ClickableViewAccessibility")
fun setBannerSliderViewPager(sliderModelList: List<SliderModel>) {
currentPage = 2
if (timer != null) {
timer!!.cancel()
}
for (x in sliderModelList.indices) {
arrangedList.add(x, sliderModelList[x])
}
arrangedList.add(0, sliderModelList[sliderModelList.size - 2])
arrangedList.add(1, sliderModelList[sliderModelList.size - 1])
arrangedList.add(0, sliderModelList[0])
arrangedList.add(1, sliderModelList[0])
val sliderAdapter = SliderAdapter()
sliderAdapter.asyncListDiffer.submitList(arrangedList)
binding.bannerSliderViewPager.apply {
adapter = sliderAdapter
clipToPadding = false
clipChildren = false
offscreenPageLimit = 3
}
val compositePageTransformer = CompositePageTransformer()
compositePageTransformer.addTransformer(MarginPageTransformer(20))
compositePageTransformer.addTransformer { page: View, position: Float ->
val r = 1 - abs(position)
page.scaleY = 0.85f + r * 0.15f
}
binding.bannerSliderViewPager.setPageTransformer(compositePageTransformer)
binding.bannerSliderViewPager.currentItem = currentPage
onPageChangeCallback = object : OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
currentPage = position
}
override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state)
if (state == ViewPager.SCROLL_STATE_IDLE) {
pageLopper(arrangedList)
}
}
}
binding.bannerSliderViewPager.registerOnPageChangeCallback(onPageChangeCallback)
startBannerSliderShow(sliderModelList)
binding.bannerSliderViewPager.setOnTouchListener { v, event ->
pageLopper(arrangedList)
timer!!.cancel()
if (event.action == MotionEvent.ACTION_UP) {
startBannerSliderShow(arrangedList)
}
false
}
}
private fun startBannerSliderShow(sliderModelList: List<SliderModel>?) {
sliderHandler = Handler()
update = Runnable {
if (currentPage >= sliderModelList!!.size) {
currentPage = 0
}
binding.bannerSliderViewPager.setCurrentItem(
currentPage++,
true
)
}
timer = Timer()
timer!!.schedule(object : TimerTask() {
override fun run() {
sliderHandler!!.post(update!!)
}
}, DELAY_TIME, PERIOD_TIME)
}
private fun stopBannerSlideShow() {
timer!!.cancel()
}
private fun pageLopper(sliderModelList: List<SliderModel>?) {
if (currentPage == sliderModelList!!.size - 2) {
currentPage = 2
binding.bannerSliderViewPager.setCurrentItem(currentPage, false)
}
if (currentPage == 1) {
currentPage = sliderModelList.size - 3
binding.bannerSliderViewPager.setCurrentItem(currentPage, false)
}
}