情境
如果你需要快速地翻閱一些連續的頁面,那麼就可以透過 ViewPager 這個元件達成這樣的效果,它是一個常見且廣泛使用的元件,簡單易懂程式碼在很多 App 上都可以看到。
程式碼下載
你可以到 GitHub 上面觀看或下載完整的程式碼。
程式碼說明
一開始我們先佈置整塊畫面就是 ViewPager,因此要將元件設定成 ViewPager,這邊要注意的是,目前採用 AndroidX 的引入函式庫方式,因此,元件名稱為 androidx.viewpager.widget.ViewPager
。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
在 MainActivity 中初始化 ViewPager 以及建立三個 PagerView 的子類別,分別為 OneView、TwoView 和 ThreeView。
class MainActivity : AppCompatActivity() {
private lateinit var pageList: MutableList<PageView>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initData()
initView()
}
private fun initView() {
pager.adapter = SamplePagerAdapter(pageList)
}
private fun initData() {
pageList = ArrayList()
pageList.add(PageOneView(this@MainActivity))
pageList.add(PageTwoView(this@MainActivity))
pageList.add(PageThreeView(this@MainActivity))
}
}
首先會發現有另外宣告一個 SamplePagerAdapter 類別,ViewPager 跟很多元件類似,可以透過 Adapter 來操作,我們宣告了一個 List 裡面裝了 View,由於要把 View 塞進 ViewPager ,因此,我宣告了一個很單純的 View 來規劃。
abstract class PageView(context: Context) : RelativeLayout(context) {
abstract fun refreshView()
}
接著根據 ViewPager 想要加入多少個 View 就繼承 PageView,如此一來,我們在 MainActivity 內就可以利用陣列來操作所有的 View 了。
class PageOneView(context: Context) : PageView(context) {
init {
val view = LayoutInflater.from(context).inflate(R.layout.page_content, null)
val textView = view.findViewById(R.id.text) as TextView
textView.text = "Page one"
addView(view)
}
override fun refreshView() {}
}
我們加入了三個 View,並且使用同一個 Layout。(只是範例, 如果你需要不同的 layout 可以自行定義)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
可以發現我們的 view_content 只有一個很單純 TextView,在 initData() 方法被呼叫的時候,把這些 View 加進去。
pageList = ArrayList()
pageList.add(PageOneView(this@MainActivity))
pageList.add(PageTwoView(this@MainActivity))
pageList.add(PageThreeView(this@MainActivity))
為什麼要讓每個 View 去繼承 PageView 呢? 理由很簡單,假設我每個 View 做了某些事情,需要重新整理,要一個一個寫 refreshview 的方法嗎?透過統一的介面處理,我們只需要在 PageView 新增一個虛擬方法 refresh,就可以讓所有 view 都去覆寫它了,這樣一來,就可以把重新整理的方法透過迴圈讓所有的 view 全部重整。
for (view in pageList) {
view.refreshView()
}
這樣一來就很方便可以管理了。
效果如下圖。