ViewPager中间大,两边pager小

Posted by アライさん on 2019年10月22日

XML布局

设置android:clipChildren=”false”,控制子视图可以超过父视图。
实现一屏幕显示多个viewpager。
设置两侧margin,留出空间给其他pager。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:clipChildren="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_marginRight="80dp"
android:layout_marginLeft="80dp"
android:clipChildren="false"
android:layout_gravity="center"
/>
</FrameLayout>

自定义ViewPager.PageTransformer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import android.view.View
import androidx.viewpager.widget.ViewPager

class ScaleInTransformer(private val minScale: Float = 0.85f) : ViewPager.PageTransformer {
private val defaultCenter = 0.5f

override fun transformPage(page: View, position: Float) {
val pageWidth = page.width
val pageHeight = page.height

page.pivotX = (pageWidth / 2f)
page.pivotY = (pageHeight / 2f)

when {
(position < -1) -> {
page.scaleX = minScale
page.scaleY = minScale
page.pivotX = pageWidth.toFloat()
}
(position <= 1) -> {
when (position < 0) {
true -> {
val scaleFactor = (1 + position) * (1 - minScale) + minScale
page.scaleX = scaleFactor
page.scaleY = scaleFactor
page.pivotX = pageWidth * ((defaultCenter * -position) + defaultCenter)
}
false -> {
val scaleFactor = (1 - position) * (1 - minScale) + minScale
page.scaleX = scaleFactor
page.scaleY = scaleFactor
page.pivotX = pageWidth * ((1 - position) * defaultCenter)
}
}
}
else -> {
page.pivotX = 0f
page.scaleX = minScale
page.scaleY = minScale
}
}

}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
adapter = object  : PagerAdapter(){
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val image = ImageView(this@MainActivity)
image.setImageResource(imgRes[position])
container.addView(image)
return image
}

override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}

override fun getCount(): Int {
return imgRes.size
}

override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
}

viewPager.pageMargin = 40
viewPager.offscreenPageLimit = 4

viewPager.adapter = adapter
viewPager.setPageTransformer(false,ScaleInTransformer())

//将frameLayout的触摸事件传递给viewPager。因为iewpager采用了margin模式,两侧有无法触摸的区域。通过这种方式解决
frameLayout.setOnTouchListener { view, motionEvent ->
viewPager.onTouchEvent(motionEvent)
}