I am trying to inflate two views in recyclerview where the condition is like "I have two views lets say view1 and view2 now while iterating over arraylist which is passed to the recycler adapter I want to check 'year' key in each object, if value of a key is new or different value than the previous object then I want to inflate the view1 which will be like header for next rows and at the same time I want to print that object where we found the new value for 'year' as a row" I am trying it with the getItemViewType() method but not able to achieve it.
I am trying it with the getItemViewType() method but not able to achieve it.
CodePudding user response:
You need to override this function to receive the correct view type
override fun getItemViewType(position: Int): Int {
if(getItem(position) is Header) return 0 else return 1
}
than in your getItemViewType() will have the correct integer that represents your view type.
CodePudding user response:
I'll assume that you are using Kotlin. First you must define a BaseItem
interface. Your Item
should extends this base interface. Then you group your items by year and add an extra item Header
. This Header
also extends the base interface above.
BaseItem.kt
interface BaseItem
Item.kt
data class Item(val year:Int,val name:String) : BaseItem
Header.kt
data class Header(val year:Int) : BaseItem
HeaderViewHolder.kt
class HeaderViewHolder(view:View):RecyclerView.ViewHolder(view){
fun bindView(item:BaseItem){
if(item !is Header) return
... // Do something
}
}
ItemViewHolder.kt
class ItemViewHolder(view:View):RecyclerView.ViewHolder(view){
fun bindView(item:BaseItem){
if(item !is Item) return
... // Do something
}
}
For the Adapter, I recommended you use ListAdapter
.
class MyAdapter : ListAdapter<BaseItem,RecyclerView.ViewHolder>(ITEM_CALLBACK){
companion object {
private val ITEM_CALLBACK = object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
if(oldItem is Header && newItem is Header) return oldItem.year==newItem.year
else if(oldItem is Item && newItem is Item) return oldItem.name == newItem.name
return false
}
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
if(oldItem is Header && newItem is Header) return oldItem==newItem
else if(oldItem is Item && newItem is Item) return oldItem == newItem
return false
}
}
}
override fun getItemViewType(position: Int): Int {
if(getItem(position) is Header) return 0
return 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder{
if(viewType==0){
val view = ... // Inflate your header view
return HeaderViewHolder(view)
}
val view = ... // Inflate your item view
return ItemViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(holder is HeaderViewHolder) holder.bindView(getItem(position))
else if(holder is ItemViewHolder) holder.bindView(getItem(position))
}
}
And in your activity, group your items and add them to a new list. Then submit the list to your adapter.
override fun onCreate(savedInstanceState:Bundle){
super.onCreate(savedInstanceState)
...
val old:List<Item> = listOf(...) // This is your original list of items
val groupMap = oldItems.groupBy{ it.year } // Group them by year
val newItems = mutableListOf<BaseItem>() // New list of base items
// Loop through the map and add an extra Header item to the new list
groupMap.forEach{ k,v->
newItems.add(Header(k))
newItems.addAll(v)
}
adapter.submitList(newItems)
...
}