关于ViewPager如何一屏多显

前言

  最近项目UI图上有个一屏显示多个Pager的控件,想了想直接通过ViewPager来实现。

实现方式

  项目地址

getPageWidth

  实际上PagerAdapter里面就提供了实现一屏多显的方法

1
2
3
4
5
6
7
8
9
10
/**
* Returns the proportional width of a given page as a percentage of the
* ViewPager's measured width from (0.f-1.f]
*
* @param position The position of the page requested
* @return Proportional width for the given page position
*/
public float getPageWidth(int position) {
return 1.f;
}

  这个方法返回的是 每个Pager的宽度 。然而,他的效果并不是我们想要的。来看看下面这段代码的运行效果。

1
2
3
override fun getPageWidth(position: Int): Float {
return 0.8f
}

  它的效果如下所示,可以看到,默认每个pager都是 局左显示 的。

getPageWidth()

clipChildren

  第二种实现方式就是通过控件的 clipChildren 属性,默认这个属性是true,我们需要将其设置为false,表示超出控件的内容范围也要显示出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#bbbbbb"
android:clipChildren="false"
android:gravity="center"
android:orientation="vertical"
tools:context="com.yanfangxiong.multipagerdemo.MainActivity">

<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:clipChildren="false"
android:overScrollMode="never"/>

</LinearLayout>

  这里将ViewPager和LinearLayout的clipChildren属性都设置为了false。然后在java代码中做如下设置。

1
2
3
4
5
6
//设置预加载的数量是3,这个值默认是1
viewPager.offscreenPageLimit = 3
//pageMargin设置页面之间的距离
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
viewPager.pageMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8f, metrics).toInt()

  效果图如下所示。

result

扩展

  感觉好像有点单调哈。我也是这么觉得的,那么我们来加点有趣的东西吧。ViewPager有个PageTransformer接口。

1
2
3
4
5
6
7
8
9
10
11
public interface PageTransformer {
/**
* Apply a property transformation to the given page.
*
* @param page Apply the transformation to this page
* @param position Position of page relative to the current front-and-center
* position of the pager. 0 is front and center. 1 is one full
* page position to the right, and -1 is one page position to the left.
*/
void transformPage(View page, float position);
}

  这里我就不写研究过程了,position的范围可以分为四段(通用的),是当前page的左上角相对于ViewPager的位置。

  1. position < -1
  2. -1 <= position < 0
  3. 0 <= position < 1
  4. position > 1

ScalePageTransformer

  于是乎我写了一个切换尺寸变换的类ScalePageTransformer,如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ScalePageTransformer(
private var minScale: Float
) : ViewPager.PageTransformer {

override fun transformPage(page: View?, position: Float) {
val size = when {
position < -1 -> minScale
position >= -1 && position < 0 -> minScale + (1 - minScale) * (1 + position)
position < 1 -> minScale + (1 - minScale) * (1 - position)
else -> minScale
}
page?.scaleY = size
}

}

  效果图如下,这样就比较有趣了,嗯,我是这么认为的。

scaleResult

RotatePageTransformer

  旋转跳跃,我闭着眼~

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
class RotatePageTransformer(
private var rotateDegree: Float
) : ViewPager.PageTransformer {

override fun transformPage(page: View?, position: Float) {
if (page == null) return

val tPivotX: Float
val degree: Float
when {
position < -1 -> {
tPivotX = page.width.toFloat()
degree = -rotateDegree
}
position >= -1 && position < 0 -> {
tPivotX = page.width.toFloat()
degree = rotateDegree * position
}
position >= 0 && position < 1 -> {
tPivotX = 0f
degree = rotateDegree * position
}
else -> {
tPivotX = 0f
degree = rotateDegree
}
}
page.apply {
pivotX = tPivotX
pivotY = if (rotateDegree < 0) 0f else page.height.toFloat()
rotation = degree
}
}

}

  来看看这个旋转变换的效果图。

rotateResult

AlphaPageTransformer

  再来个透明度变化的吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class AlphaPageTransformer(
private var minAlpha: Float
) : ViewPager.PageTransformer {

override fun transformPage(page: View?, position: Float) {
val alpha: Float = when {
position < -1 -> minAlpha
position >= -1 && position < 0 -> minAlpha + (1 - minAlpha) * (1 + position)
position >= 0 && position < 1 -> minAlpha + (1 - minAlpha) * (1 - position)
else -> minAlpha
}
page?.alpha = alpha
}

}

  效果图如下

alphaResult

毒鸡汤

  日子还长,别太失望~

本文标题:关于ViewPager如何一屏多显

文章作者:严方雄

发布时间:2018-03-05

最后更新:2018-09-13

原始链接:http://yanfangxiong.com/2018/03/05/关于ViewPager如何一屏多显/

0%