---
# System prepended metadata

title: Android ViewPager2
tags: [Android, ViewPager2]

---

###### tags: `Android`, `ViewPager2`

# Android ViewPager2

> ViewPager 已於 April 1, 2020釋出1.0.0版, 特來嚐鮮一下
> 並記錄自己挖掘的內容

[Toc]
# 用法

## gradle 設置
```groovy=
implementation "androidx.viewpager2:viewpager2:1.0.0"
```

## 要點

### Adapter
由於ViewPager2實際上是由RecyclerView 封裝而成的, 因此Adapter是吃RecyclerView.Adapter

```kotlin=
view_pager.adapter = ViewPager2Adapter(arrayListOf("a", "b", "c"))

class ViewPager2Adapter(
    private val mData: MutableList<String> = arrayListOf()
): RecyclerView.Adapter<ViewPager2Adapter.Holder>() {

    // implement function
    
}
```
---
### mOffscreenPageLimit
在其source code裡有一段這麼寫:

```java=
public static final int OFFSCREEN_PAGE_LIMIT_DEFAULT = -1;

...

int mOffscreenPageLimit = OFFSCREEN_PAGE_LIMIT_DEFAULT;
```
`mOffscreenPageLimit` 是用來控制, 提前加載幾個畫面的變數。

(`mOffscreenPageLimit = 1` 就是提前加載前後一個畫面)

以前的ViewPager 有限制其數字必定要 > 0, 而現在則是能改成 -1, 以及 > 0 的數字

如果此值為-1, 則由RecycleView 的 cache 方式, 進行畫面的優化。

想看更詳細的人, 可以參考以下function 的說明
```java=
public void setOffscreenPageLimit(@OffscreenPageLimit int limit) {
    ...
}
```
---
### TabLayout 的結合
```groovy=
implementation('com.google.android.material:material:1.1.0')
```
viewPager一樣使用 `setupWithViewPager(viewPager)` 的方法

而ViewPager2 出來後, google 寫了一個class `TabLayoutMediator`, 專門來綁定這兩個View。

從意義上/架構來說, 確實是一個比較好的做法
```kotlin=
TabLayoutMediator(tab_layout, view_pager) { tab, position ->
    tab.text = "tab${position + 1}"
}.attach()
```

裡面主要也是互相register Listener:

```java=
// Add our custom OnPageChangeCallback to the ViewPager
onPageChangeCallback = new TabLayoutOnPageChangeCallback(tabLayout);
viewPager.registerOnPageChangeCallback(onPageChangeCallback);

// Now we'll add a tab selected listener to set ViewPager's current item
onTabSelectedListener = new ViewPagerOnTabSelectedListener(viewPager);
tabLayout.addOnTabSelectedListener(onTabSelectedListener);

```

同時也提供`detach()` 

---
### Orientation
可以設置 `ORIENTATION_HORIZONTAL`, `ORIENTATION_VERTICAL`

來改變滾動的方向, 因此可以左右滑, 也可以上下動。
```java=
public void setOrientation(@Orientation int orientation) 
```
---
### fakeDrag
相關function: `fakeDragBy(float)`, `beginFakeDrag()`, `endFakeDrag()`, `isFakeDragging()`

這個有點酷, 他提供用programming 的方式, 去滑動View

使用前後要分呼叫 `beginFakeDrag`, `endFakeDrag`

`fakeDragBy(float)`, 則是讓你滑動View, 單位是`px`

---
### User Input Enable
禁止使用者滑動View
```java=
public void setUserInputEnabled(boolean enabled)
```
---
### 其他 

原本ViewPager就有的功能, 以及RecyclerView的一部分也加了進來

- registerOnPageChangeCallback
- setPageTransformer
- addItemDecoration
- ...

並沒有太大的差別, 就留給讀者自己去看看吧～

> 還有一件有趣的事, 如果你企圖在`ViewPager2` 直接 `addView`, 會吐
> `IllegalStateException: ViewPage2 does not support direct child views`
> 
> 禁止你新增一個`View` 到`ViewPager2`裡面, 你可以在`onViewAdded(View child)`看到
> 
> 但是沒有擋`removeView`, 所以你可以把`RecyclerView` 刪掉, ㄎ

## 畫面
最後附上用ViewPager2 實作出來的簡單畫面

主要是用`PageTransformer` 做出來

因為看起來很炫炮就模仿做了一個~

[ViewPager2 demo on GitHub](https://github.com/nacro711072/ViewPager2Demo)


![](https://i.imgur.com/cDJoAEO.png =50%x)

![](https://i.imgur.com/Ctb2iIK.png =50%x)
