ViewPager2
中没有过度滚动的方法,我需要检测过度滚动,以便在没有更多页面时可以将用户带回主页。
ViewPager2 没有用于过度滚动的公共方法,但是,可以通过监听来检测到
onPageScrollStateChanged
通常,当更改页面时,
onPageScrollStateChanged
中滚动状态的事件转换为SCROLL_STATE_DRAGGING
-> SCROLL_STATE_SETTLING
-> SCROLL_STATE_IDLE
但是如果过度滚动,顺序是
SCROLL_STATE_DRAGGING
-> SCROLL_STATE_IDLE
private fun listenOverScroll(currentIndex: Int, size: Int) {
var index = currentIndex
var previousState = ViewPager2.SCROLL_STATE_IDLE
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
index = position
}
override fun onPageScrollStateChanged(state: Int) {
Log.d(TAG,"Index:: $index | state:: $state | prevState:: $previousState")
super.onPageScrollStateChanged(state)
if ((index >= size - 1 || index <= 0)// end of list. these checks can be
// used individualy to detect end or start of pages
&& previousState == ViewPager2.SCROLL_STATE_DRAGGING // from DRAGGING
&& state == ViewPager2.SCROLL_STATE_IDLE) { // to IDLE
Log.d(TAG,"OVERSCROLL:: Index:: $index | state:: $state | prevState:: $previousState")
//overscroll performed. do your work here
}
previousState = state
}
})
}
我认为这是一个更清晰、更干净的解决方案。
private fun viewPagerScrollStateListener() {
binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
private var scrolling = false
override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state)
scrolling = when (state) {
ViewPager2.SCROLL_STATE_DRAGGING -> true
ViewPager2.SCROLL_STATE_SETTLING -> true
ViewPager2.SCROLL_STATE_IDLE -> {
if (scrolling && isLastPage()) {
// Scrolling has ended and we are on the last page
onEndScroll()
}
false
}
else -> false
}
}
private fun isLastPage(): Boolean {
return binding.viewPager.currentItem + 1 == adapter.itemCount
}
private fun onEndScroll() {
Log.i("ViewPager", "End of scrolling")
}
})
}