Hi I'm using recyclerview for handling multiviewType of the lists, but when i scroll the cells are changing sometimes.
I referred many SO's answer but it didnt worked.
Override the getitemid as well but didnt worked need help for the following code.
Here is my code of my adapter:-
Код: Выделить всё
class Adapter(val onItemClick: (Data) -> Unit) :
BaseRecyclerViewAdapter() {
companion object {
const val VIEW_LINK = 1
const val VIEW_POST = 2
const val VIEW_LOADER = 3
}
override fun createItemViewHolder(
parent: ViewGroup,
viewType: Int
): BaseRecyclerViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
when (viewType) {
VIEW_LINK -> {
return LinkViewHolder(
LayoutLinkPreviewBinding.inflate(
layoutInflater,
parent,
false
)
)
}
VIEW_POST -> {
return PostViewHolder(
LayoutPostPreviewBinding.inflate(
layoutInflater,
parent,
false
)
)
}
else -> {
return LoadMoreViewHolder(
ItemProgressLoadMoreBinding.inflate(
layoutInflater,
parent,
false
).root
)
}
}
}
override fun bindItemViewHolder(holder: BaseRecyclerViewHolder, position: Int) {
when (holder.itemViewType) {
VIEW_LINK -> {
items.let {
(holder as LinkViewHolder).bind(it[position])
}
}
VIEW_POST -> {
items.let {
(holder as PostViewHolder).bind(it[position])
}
}
VIEW_LOADER -> {
(holder as LoadMoreViewHolder).pdLoadMore.show()
}
}
}
override fun getItemViewType(position: Int): Int {
return when (items[position].type) {
"link" -> {
VIEW_LINK
}
"post" -> {
VIEW_POST
}
"media" -> {
VIEW_POST
}
else -> {
VIEW_LOADER
}
}
}
inner class LinkViewHolder(private val layoutLinkPreviewBinding: LayoutLinkPreviewBinding) :
BaseRecyclerViewHolder(layoutLinkPreviewBinding.root) {
private var coroutineScope: CoroutineScope? = null
var link: String? = null
override fun bind(item: Data) {
ensureCoroutineScope()
fetchLinkPreview(item)
}
}
inner class PostViewHolder(private val postPreviewBinding: LayoutPostPreviewBinding) :
BaseRecyclerViewHolder(postPreviewBinding.root) {
override fun bind(item: Data) {
setUpUI(item)
}
}
inner class LoadMoreViewHolder(itemView: View) :
BaseRecyclerViewHolder(itemView) {
var pdLoadMore: loaderView
init {
pdLoadMore = itemView.findViewById(R.id.pdLoadMore)
}
override fun bind(item: ShowCaseData) {}
}
override fun getItemId(position: Int): Long {
return items[position].hashCode().toLong()
}
base recycler:-
Код: Выделить всё
abstract class BaseRecyclerViewAdapter : RecyclerView.Adapter() {
/**
* list of all items
*/
private var _items = mutableListOf()
var items: List = _items
private set
var isLoadingAdded = false
/**
* create view holder of recycler view item
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
return createItemViewHolder(parent, viewType)
}
/**
* bind recycler view item with data
*/
override fun onBindViewHolder(holder: T, position: Int) {
bindItemViewHolder(holder, position)
}
/*
* If the payloads list is not empty,the ViewHolder is currently bound to old data and Adapter may run an efficient partial
* update using the payload info. If the payload is empty, Adapter must run a full bind.
*/
override fun onBindViewHolder(holder: T, position: Int, payloads: MutableList) {
if (payloads.isNotEmpty()) {
bindItemViewHolderPayload(holder, position, payloads)
} else {
bindItemViewHolder(holder, position)
}
}
/**
* get count for visible count
*/
override fun getItemCount() = _items.size
/**
* abstract method to create custom view holder
*/
protected abstract fun createItemViewHolder(
parent: ViewGroup,
viewType: Int
): T
/**
* abstract method to bind custom data
*/
protected abstract fun bindItemViewHolder(holder: T, position: Int)
/**
* abstract method to bind custom data using payloads
*/
protected open fun bindItemViewHolderPayload(holder: T, position: Int,payloads: MutableList){}
/**
* add all items to list
*/
fun addAll(items: List, clearPreviousItems: Boolean = false) {
if (clearPreviousItems) {
this._items.clear()
}
this._items.addAll(items)
notifyDataSetChanged()
}
/**
* add all items to list with notifyrangechanged
*/
fun addAll(items: List, clearPreviousItems: Boolean = false , existingSize :Int) {
if (clearPreviousItems) {
this._items.clear()
}
this._items.addAll(items)
notifyItemRangeInserted(existingSize,items.size)
}
/**
* add item (at position - optional)
*/
fun addItem(item: S, position: Int = _items.size, clearPreviousItems: Boolean = false) {
var adapterPosition = position
if (clearPreviousItems) {
this._items.clear()
adapterPosition = 0 // set position to 0 after items arrayList gets clear
}
this._items.add(adapterPosition, item)
notifyItemInserted(adapterPosition)
}
/**
* remove item from position
*/
fun removeItem(position: Int) {
if (position != -1) {
_items.removeAt(position)
notifyItemRemoved(position)
}
}
/**
* get item at position
*/
fun getItemAt(position: Int): S {
return _items[position]
}
/**
* update item at position
*/
fun updateItemAt(position: Int, item: S) {
if (position != -1) {
_items[position] = item
notifyItemChanged(position)
}
}
/**
* update item at position with payload
*/
fun updateItemAtWithPayload(position: Int, item: S, payload:Any?) {
if (position != -1) {
_items[position] = item
notifyItemChanged(position , payload)
}
}
/**
* To clear the adapter
*/
fun clearAdapter() {
_items.clear()
notifyDataSetChanged()
}
fun showLoadMore(loadMoreItem: S) {
if (!isLoadingAdded) {
isLoadingAdded = true
addItem(loadMoreItem)
}
}
fun hideLoadMore() {
if (isLoadingAdded) {
isLoadingAdded = false
removeItem(itemCount - 1)
}
}
fun isEmpty(): Boolean {
return _items.size == 0
}
please help Thanks in advance
Источник: https://stackoverflow.com/questions/781 ... -scenarios