簡體   English   中英

如何在 Kotlin 的 RecyclerView 頂部添加默認靜態項?

[英]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()區分兩種類型的行。 應更新onCreateViewHolderonBindViewHolder以處理正在創建/綁定的行類型。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM