2

I try to create a RecyclerView with two different layouts, one for the header and the other for the body.
Here is my adapter code:

class ProductChoicesAdapter(private val listener: OnProductChoicesClickListener) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>(),
    ProductChoiceOptionAdapter.OnChoiceOptionClickListener {

    companion object {
        const val VIEW_TYPE_SIZE = 1
        const val VIEW_TYPE_OTHER = 2
    }

    private val viewPool = RecyclerView.RecycledViewPool()
    var productChoicesList: List<ProductChoice>? = null
        set(value) {
            field = value
            val temp = mutableListOf<String>()
            value?.let {
                if (value.isNotEmpty())
                    for (option in it[0].options)
                        temp.add(option.id)
            }
            priceChoiceIdList = temp
            notifyDataSetChanged()
        }
    var priceChoiceIdList = listOf<String>()
    var priceChoiceId: String? = null
    var otherChoiceId = HashMap<String, String>()

    override fun getItemCount(): Int = productChoicesList?.size ?: 0

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            VIEW_TYPE_SIZE -> {
                val binding = ItemRecyclerviewFeatureSizeBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
                SizeViewHolder(binding)
            }
            VIEW_TYPE_OTHER -> {
                val binding = ItemRecyclerviewOtherFeatureBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
                OtherChoiceViewHolder(binding)
            }
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val currentItem = productChoicesList!![position]
        when (holder) {
            is ProductChoicesAdapter.SizeViewHolder -> holder.bind(currentItem)
            is ProductChoicesAdapter.OtherChoiceViewHolder -> holder.bind(currentItem)
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun getItemViewType(position: Int): Int {
        Log.e("getItemViewType", "position= $position") // It is print 0 for 3 times
        return when (position) {
            0 -> VIEW_TYPE_SIZE
            else -> VIEW_TYPE_OTHER
        }
    }

    private inner class SizeViewHolder(private val binding: ItemRecyclerviewFeatureSizeBinding) :
        RecyclerView.ViewHolder(binding.root) {
        init {
            binding.textSizeGuide.setOnClickListener {
                listener.onSizeGuideClick()
            }
        }
        fun bind(productChoice: ProductChoice) {
            binding.recyclerviewSize.apply {
                setRecycledViewPool(viewPool)
                adapter =
                    ProductChoiceOptionAdapter(
                        productChoice.title,
                        productChoice.options,
                        this@ProductChoicesAdapter
                    )
            }
        }
    }

    private inner class OtherChoiceViewHolder(private val binding: ItemRecyclerviewOtherFeatureBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(productChoice: ProductChoice) {
            binding.apply {
                textTitle.text = productChoice.title
                recyclerviewOptions.setRecycledViewPool(viewPool)
                recyclerviewOptions.adapter =
                    ProductChoiceOptionAdapter(
                        productChoice.title,
                        productChoice.options,
                        this@ProductChoicesAdapter
                    )
            }
        }
    }

    interface OnProductChoicesClickListener {
        fun onSizeGuideClick()
        fun onPriceOptionClick(productChoiceOption: ProductChoiceOption)
    }

    override fun onOptionClick(title: String?, option: ProductChoiceOption?) {
        option?.let { option ->
            if (priceChoiceIdList.contains(option.id)) {
                priceChoiceId = option.id
                listener.onPriceOptionClick(option)
            } else {
                title?.let { title ->
                    otherChoiceId.put(title, option.id)
                }
            }
        }
    }
}

I checked that productChoicesList contains 3 Items. But it always creates and displays the first item in recyclerview. Also, I checked that Log.e("getItemViewType", "position= $position") in getItemViewType() print position= 0 3 times.
I wonder why position in getItemViewType() be always 0!
Any idea?

Kaaveh Mohamedi
  • 1,399
  • 1
  • 15
  • 36
  • [https://stackoverflow.com/a/26920133/6203398](https://stackoverflow.com/a/26920133/6203398) I think this answer will help you. – Aref Akbari Mar 14 '21 at 05:43

1 Answers1

0

Finally, I figure out what's happening. Mistakenly I set android:orientation="horizontal" in my RecyclerView, so it works correctly but I must scroll horizontally to see other items!

Kaaveh Mohamedi
  • 1,399
  • 1
  • 15
  • 36