[英]How to add a default static item at the top in a RecyclerView in Kotlin?
我想讓一個項目始終出現在RecyclerView
的頂部。 我正在從Firestore
獲取數據並將它們顯示在RecyclerView
。 我想要的是出現在列表頂部的項目,然后顯示從Firestore
獲取的項目。 我怎樣才能做到這一點?
以下是我的適配器。
open class CategoryListAdapter(private val context: Context, private var list: ArrayList<Categories>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var onClickListener: OnClickListener? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(
BottomsheetCategoryListLayoutBinding.inflate(
LayoutInflater.from(
parent.context
), parent, false
)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = list[position]
if (holder is MyViewHolder) {
GlideLoader(context).loadPicture(model.category_image, holder.binding.ivCategoryImage)
holder.binding.tvCategoryName.text=model.category_name
}
holder.itemView.setOnClickListener {
if (onClickListener != null) {
onClickListener!!.onClick(position, model)
}
}
}
override fun getItemCount(): Int {
return list.size
}
fun setOnClickListener(onClickListener: OnClickListener) {
this.onClickListener = onClickListener
}
interface OnClickListener{
fun onClick(position: Int, category: Categories)
}
private class MyViewHolder(val binding: BottomsheetCategoryListLayoutBinding) : RecyclerView.ViewHolder(binding.root)
}
您可以按照此處的說明使用 ConcatAdapter。
或者您可以創建一個 Adapter 來處理多種類型的行。 我更喜歡這樣做,因為它可以靈活地將子標題移動到列表中的不同位置。
創建一個密封接口來表示任一類型的行項目(標題或您的類別類)。
sealed interface CategoriesListItem
// For now we can use a singleton object. If you have non-static data
// to be placed in the header, you'll need a class so you can hold that
// data and bind it in `onBindViewHolder`.
object: CategoriesHeader: CategoriesListItem
// Your existing Categories class, now implementing the sealed interface:
data class Categories(/*...*/): CategoriesListItem
使您的列表類型為<CategoriesListItem>
而不是<Categories>
,並將CategoriesHeader
作為列表中的第一項。
目前,您似乎在適配器中使用了一個可變列表。 我建議切換到 ListAdapter,每次發生更改時,您都可以在其中使用新的 List 實例調用submitList
,並且它可以有效地為您設置動畫。 進行此切換時,您需要將CategoriesHeader
作為每個列表中的第一項包含在內。
在您的適配器中,覆蓋getItemViewType()
,您可以使用常量getItemViewType()
區分兩種類型的行。 應更新onCreateViewHolder
和onBindViewHolder
以處理正在創建/綁定的行類型。
class CategoryListAdapter(private val context: Context, private var list: ArrayList<CategoriesListItem>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val VIEW_TYPE_HEADER = 0
const val VIEW_TYPE_CATEGORIES = 1
}
private var onClickListener: OnClickListener? = null
override fun getItemViewType(position: Int) = when (list[position) {
CategoriesHeader -> VIEW_TYPE_HEADER
is Categories -> VIEW_TYPE_CATEGORIES
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = when (viewType) {
VIEW_TYPE_HEADER -> MyHeaderViewHolder( /* ... */ )
VIEW_TYPE_CATEGORIES -> MyViewHolder(
BottomsheetCategoryListLayoutBinding.inflate(
LayoutInflater.from(
parent.context
), parent, false
)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val viewType = getItemViewType(position)
if (viewType == VIEW_TYPE_HEADER) {
return // assuming there's no specific data to put in the header
}
val model = list[position]
if (holder is MyViewHolder) {
GlideLoader(context).loadPicture(model.category_image, holder.binding.ivCategoryImage)
holder.binding.tvCategoryName.text=model.category_name
}
holder.itemView.setOnClickListener {
if (onClickListener != null) {
onClickListener!!.onClick(position, model)
}
}
}
override fun getItemCount(): Int {
return list.size
}
fun setOnClickListener(onClickListener: OnClickListener) {
this.onClickListener = onClickListener
}
interface OnClickListener{
fun onClick(position: Int, category: Categories)
}
private class MyHeaderViewHolder(val binding: SomeHeaderViewBinding) : RecyclerView.ViewHolder(binding.root)
private class MyViewHolder(val binding: BottomsheetCategoryListLayoutBinding) : RecyclerView.ViewHolder(binding.root)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.