RecyclerView | 在 RecyclerView 中使用 header 快人一步

本文是介紹 RecyclerView 入門基礎 系列文章 的第四篇。若是您已經對建立 RecyclerView 有了必定的認識,請繼續閱讀本文。若是還沒有熟悉,建議您首先閱讀本系列中的 第一篇文章android

您能夠經過在 RecyclerView 中添加 Header 來爲應用數據補充上下文信息。雖然您也能夠在 LinearLayout 中將 TextView 置於 RecyclerView 之上來模擬 header 的效果,可是這個模擬的 header 在用戶滑動屏幕的時候甚至是滑到列表底部的時候仍然會駐留在屏幕上。而使用真正的 header 元素,您能夠實如今用戶滑動 RecyclerView 的時候,header 隨之移動到屏幕以外。git

本文中的示例會在 RecyclerView 中添加 Header,列表中會顯示不一樣類型的花。Header 顯示 "Flower Finder",而且顯示列表中花的數量。github

建立 header 佈局

建立一個佈局文件,其中定義 Header 的展現效果。app

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <TextView
    android:id="@+id/header_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/flower_finder"
    android:textAppearance="?attr/textAppearanceHeadline3" />

  <TextView
    android:id="@+id/flower_number_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:textAppearance="?attr/textAppearanceHeadline6" />

  <TextView
    android:id="@+id/flower_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/flower_string"
    android:textAppearance="?attr/textAppearanceHeadline6" />

</LinearLayout>

建立 HeaderAdapter 和 HeaderViewHolder

建立新文件來請求而且綁定 Header 的視圖。ide

HeaderAdapter 繼承自 RecyclerView.Adapter<RecyclerView.ViewHolder>()函數

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class HeaderAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>(){

}

HeaderAdapter 中,添加一個繼承自 RecyclerView.ViewHolderViewHolder。若是您須要動態更新文本,添加一個變量表明須要更新內容的 TextView。建立 bind() 函數來使用傳入的字符串更新 TextView。佈局

<!-- Copyright 2019 Google LLC. 
    SPDX-License-Identifier: Apache-2.0 -->
 
 class HeaderViewHolder(view: View) : RecyclerView.ViewHolder(view){
   private val flowerNumberTextView: TextView = itemView
     .findViewById(R.id.flower_number_text)
 
   fun bind(flowerCount: Int) {
     flowerNumberTextView.text = flowerCount.toString()
  }
}

在類定義中,修改 Adapter 的參數表以接收 HeaderViewHolderpost

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class HeaderAdapter: RecyclerView.Adapter<HeaderAdapter.HeaderViewHolder>() {

}

因爲 Adapter 繼承自 RecyclerView.Adapter,它須要實現 onCreateViewHolder()onBindViewHolder()getItemCount()google

  • onCreateViewHolder() 負責填充視圖而且返回 HeaderViewHolder
  • getItemCount() 僅返回數值 1,由於僅有一個 Header 元素
  • onBindViewHolder() 將數據綁定到 Header
<!-- Copyright 2019 Google LLC. 
    SPDX-License-Identifier: Apache-2.0 -->
 
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
     val view = LayoutInflater.from(parent.context)
         .inflate(R.layout.header_item, parent, false)
     return HeaderViewHolder(view)
 }
 
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
    holder.bind(flowerCount)
}

override fun getItemCount(): Int {
    return 1
}

在 Activity 類中使用 ConcatAdapter

在 Activity 類中,建立一個變量表明 HeaderAdapter(),並將其置於 RecyclerView 的 Adapter 之上。spa

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

val headerAdapter = HeaderAdapter()
val flowersAdapter = FlowersAdapter { flower -> adapterOnClick(flower) }

而後使用 ConcatAdapter 將這兩個 adapter 添加到 RecyclerViewConcatAdapter 會依次顯示多個Adapter 的內容。在 flowersAdapter 以前添加 headerAdapter

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

val concatAdapter = ConcatAdapter(headerAdapter, flowersAdapter)
recyclerView.adapter = concatAdapter

運行代碼。大功告成!添加 Header 就是這麼簡單。

下一步

關於 Header 的完整示例代碼,請查閱: https://github.com/android/views-widgets-samples/tree/main/RecyclerViewKotlin

感謝閱讀 RecyclerView 系列 的最後一篇。若是您還沒有閱讀本系列中的其它文章,歡迎查閱如下列表並閱讀。