開工前準備
本篇使用了第三方的 library - SectionedRecyclerViewAdapter 來協助我們加速建立 RecyclerView Section,別人都幫我們寫好了,還有世界各國的貢獻者幫忙抓 bug,不拿來用實在太可惜啦 XD。
我們使用 Android Studio 開發,開始前先建立一個 Android project。範例程式以 Kotlin 撰寫,使用 Java 開發的同學,可以先了解用法,再到文末 Github 查看完整的程式碼與目錄結構。
匯入 Library
在專案 Gradle 裡匯入 library,再按下 Sync Now:
implementation 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:3.1.0'
*此 library 3.1.0 版僅支援 Androidx,使用 android.support 的同學請匯入 1.2.0 版。
XML 資源檔與 Adapter
在 activity_main.xml 加入一個 RecyclerView:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
新增標題和內容要用到的 XML 資源檔
header.xml
<?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:orientation="vertical"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/headerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_gravity="center"
tools:text="標題" />
</LinearLayout>
item.xml
<?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:orientation="vertical"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/itemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="15sp"
tools:text="內容" />
</LinearLayout>
接著新增 Adapter。
SectionAdapter.kt
class SectionAdapter(
private val context: Context,
private val header: String,
private val item: Array<String>
) :
Section(
SectionParameters.builder()
.itemResourceId(R.layout.item)
.headerResourceId(R.layout.header)
.build()
) {
override fun getContentItemsTotal(): Int {
return item.size
}
override fun getHeaderViewHolder(view: View): ViewHolder {
return HeaderViewHolder(view)
}
override fun getItemViewHolder(view: View): ViewHolder {
return ItemViewHolder(view)
}
override fun onBindHeaderViewHolder(holder: ViewHolder) {
val headerHolder = holder as HeaderViewHolder
headerHolder.headerText.text = header
}
override fun onBindItemViewHolder(holder: ViewHolder, position: Int) {
val itemHolder = holder as ItemViewHolder
itemHolder.itemText.text = item[position]
itemHolder.itemText.setOnClickListener {
Toast.makeText(context, "正在點擊: $header 的 ${item[position]}", Toast.LENGTH_SHORT).show()
}
}
internal inner class HeaderViewHolder(itemView: View) : ViewHolder(itemView) {
val headerText: TextView = itemView.headerText
}
internal inner class ItemViewHolder(itemView: View) : ViewHolder(itemView) {
val itemText: TextView = itemView.itemText
}
}
我們將來可以在 onBindHeaderViewHolder
方法控制標題的行為;在 onBindItemViewHolder
方法控制第 position 內容的行為。
MainActivity 要做什麼?
在 MainActivity,我們先宣告此次範例要放進 RecyclerView 的標題與內容:
private val header1 = "A"
private val header2 = "B"
private val header3 = "C"
private val item1: Array<String> = arrayOf("001", "002", "003", "004", "005", "006")
private val item2: Array<String> = arrayOf("007", "008", "009", "010", "011", "012")
private val item3: Array<String> = arrayOf("013", "014", "015", "016", "017", "018")
private val ITEM_PER_LINE: Int = 4
接著建立 SectionedRecyclerViewAdapter 物件,新增三個 SectionAdapter:
val sectionAdapter = SectionedRecyclerViewAdapter()
sectionAdapter.addSection(SectionAdapter(this, header1, item1))
sectionAdapter.addSection(SectionAdapter(this, header2, item2))
sectionAdapter.addSection(SectionAdapter(this, header3, item3))
定義 GridLayout 顯示方式,標題佔一列,內容每列四行:
val glm = GridLayoutManager(this, ITEM_PER_LINE)
glm.spanSizeLookup = object : SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (sectionAdapter.getSectionItemViewType(position) == SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER) {
ITEM_PER_LINE
} else {
1
}
}
}
設定 Adpater:
recyclerView.layoutManager = glm
recyclerView.adapter = sectionAdapter
做完了?沒錯,就是這麼簡單
趕快執行看看吧!是不是很簡單呢。
接著,只要在 MainActivity 設定你想顯示的標題和內容、顯示佈局,改寫 onBindHeaderViewHolder
和 onBindItemViewHolder
的行為,就可以自訂你的 RecyclerView Section了。