实现画廊效果首先我们要考虑的是,如何让ViewPager2同时显示多个页面Item。也就是一起显示前后的两个item
思路:给ViewPager2左边和右边设置一个margin、固定ViewPager大小或者根据想要显示的Item个数动态计算ViewPager的大小,然后设置clipChildren=false,允许ViewPager中看不到的界面绘制出来。
clipChildren:我们知道,在Android中,布局中的控件超出父布局的大小部分不会被绘制,但是当clipChildren设置为false时,子View的内容可以超出父布局被绘制出来。
设置效果如上
其次,我们需要设置每个页面Item的间距,ViewPager2和ViewPager不同,ViewPager使用setPageMargin,但是因为ViewPager2内部是RecyclerView,有类似addItemDecoration的功能,我们添加自带的MarginPageTransformer
然后我们还要为ViewPager2添加一个画廊缩放的效果,ViewPager2的页面切换效果是通过PageTransformer实现的
class ZoomOutPageTransformer : ViewPager2.PageTransformer {
companion object {
//自由控制缩放比例
private const val MIN_SCALE_Y = 0.8f //0.85f
}
override fun transformPage(page: View, position: Float) {
if (position >= 1 || position <= -1) {
page.scaleY = MIN_SCALE_Y
} else if (position < 0) {
// -1 < position < 0
//View 在再从中间往左边移动,或者从左边往中间移动
val scaleY = MIN_SCALE_Y + (1 + position) * (1 - MIN_SCALE_Y)
page.scaleY = scaleY
} else {
// 0 <= positin < 1
//View 在从中间往右边移动 或者从右边往中间移动
val scaleY = (1 - MIN_SCALE_Y) * (1 - position) + MIN_SCALE_Y
page.scaleY = scaleY
}
}
}
目前我们已经为ViewPager2设置过一个PageTransformer了,ViewPager2为我们提供了CompositePageTransformer,可以同时设置多个PageTransformer如下:
viewPager.setPageTransformer(CompositePageTransformer().apply {
addTransformer(ZoomOutPageTransformer())
addTransformer(MarginPageTransformer(16f.dp(context)))
})
因为我们设置了ViewPager的宽度是没有填满根布局的,所以边缘部分并不能滑动。可以将根布局的Touch事件直接传递给ViewPager中的RecyclerView
override fun onTouchEvent(event: MotionEvent?): Boolean {
return mViewPager.getChildAt(0).onTouchEvent(event)
}
到这,达到了我们期望的效果