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?