viewpage 做无限滑动,大家都知道的一种伪无限方法,就不赘述了。感觉不太好,对性能也会有影响。往左滑动还要计算中间值......
这里简单说一下另外一种方法,原理就是 注册 registerOnPageChangeCallback 在回调中 通过设置 setCurrentItem。步骤如下:
1.加工数据源
例如真实的数据源为 1 2 3 4 5 ,那么在设置给adapter前 改造成 5 1 2 3 4 5 1,就是第一项添加最后一个数据,最后一项添加第一个数据。
2.设置viewpage启动项
假设我们初始化时显示第一项数据。那么就设置 setCurrentItem 为1
val list :List<String> = listOf("我是第5页","我是第一页","我是第二页","我是第三页","我是第四页","我是第5页","我是第一页")
binding.vp2.adapter = MyAdapter(list)
binding.vp2.setCurrentItem(1,false)
3.注册滑动监听
通过 registerOnPageChangeCallback 在 onPageSelected 中进行处理,代码如下,一看就明白了。由于源数据首位各添加了最后一项及第一项数据,保证向左向右滑动到边界时可以继续滑动。当滑动到第0页或最后一页时,做页面切换。
override fun onPageSelected(position: Int) {
Log.e("111111","onPageSelected-1: pos:$position")
if(currentPos == 0){
binding.vp2.setCurrentItem(list.size - 2,false)
}
if(currentPos == list.size -1){
binding.vp2.setCurrentItem(1,false)
}
}
4.细节处理
做到第三步时 基本就实现了我们的需求,但是会有个问题 onPageSelected事件是滑动选择页面之后,而实际上页面切换后后,还会一部分的滑动动画。这个时候进行setCurrentItem,会导致页面这部分动画丢失。解决办法看另一个回调方法:onPageScrollStateChanged
此时需要将 当前滑动的页号记录下来。调整一下逻辑:
var currentPos = 1
binding.vp2.registerOnPageChangeCallback (object : OnPageChangeCallback(){
override fun onPageSelected(position: Int) {
currentPos = position
Log.e("111111","onPageSelected-1: pos:$position")
}
override fun onPageScrollStateChanged(state: Int) {
Log.e("111111","onPageScrollStateChanged-3: state:$state")
if(state == 0){
if(currentPos == 0){
binding.vp2.setCurrentItem(list.size - 2,false)
}
if(currentPos == list.size -1){
binding.vp2.setCurrentItem(1,false)
}
}
}
})
onPageScrollStateChanged 中的 state = 0 代表此时动画已经结束,那么在这个时候做setCurrentItem就最适合不过啦。是不是更丝滑了些呢!!!!