Hello. I am trying to find a way by which it could work with a list adapter or with a regular recycler adapter but updating the mappings when list content is updated. currently the mappings remain the same and it causes a crash. can you help?
Here is my list adapter file :
class Adp: ListAdapter<String,CityVH>(DIFFER), SectionIndexer {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = CityVH(ItemRvBinding.inflate(LayoutInflater.from(parent.context),parent,false))
override fun onBindViewHolder(holder: CityVH, position: Int) {
holder.bind(getItem(position)?:"")
}
private val sideCharToMainDataPositionMap = hashMapOf<Char,Int>()
override fun getSections(): Array<String> {
logger("getSections() called")
val sideScrollerEntries = getSectionEntries()
prepareMapping(sideScrollerEntries)
return sideScrollerEntries.map { it.toString() }.toTypedArray()
}
private fun prepareMapping(sideScrollerEntries: Array<Char>) {
logger("prepareMapping() called with: sideScrollerEntries = ${sideScrollerEntries.contentToString()}")
val uniqueCharsAndIndices = currentList
.mapIndexed { index, s -> s.first() to index } //take 1st char of each entry and its associated position
.distinctBy { it.first }// filter out all the duplicates
val uniqueChars: List<Char> = uniqueCharsAndIndices.map { it.first }
val uniqueCharIndices = uniqueCharsAndIndices.map { it.second }
logger("uniqueCharsAndIndices: $uniqueCharsAndIndices")
if (uniqueCharIndices.isEmpty()) return
sideCharToMainDataPositionMap.clear()
var lastCharIdx = uniqueCharIndices.first()
sideScrollerEntries.forEach {
if (it in uniqueChars) {
val assocIdx = uniqueChars.indexOf(it)
val assocUniqueCharPlacementIdx = uniqueCharIndices[assocIdx]
sideCharToMainDataPositionMap[it] = assocUniqueCharPlacementIdx
lastCharIdx = assocUniqueCharPlacementIdx
} else {
sideCharToMainDataPositionMap[it] = lastCharIdx
}
}
logger("sideCharToMainDataPositionMap: $sideCharToMainDataPositionMap")
}
private fun getSectionEntries():Array<Char>{
logger( "getSectionEntries() called. currentList=$currentList")
val all = ALL_CHARS.map { it }.toTypedArray()
val onlyAvailable = currentList.map { it.first() }.distinct().toTypedArray()
return onlyAvailable
}
override fun getPositionForSection(charIndex: Int): Int {
val char = getSectionEntries().getOrNull(charIndex)
val assocRecyclerPosition = sideCharToMainDataPositionMap[char] ?:0
logger("getPositionForSection() called with: charIndex = $charIndex | assoc char=$char |assocRecyclerPosition=$assocRecyclerPosition")
return assocRecyclerPosition
}
override fun getSectionForPosition(position: Int): Int {
logger( "getSectionForPosition() called with: position = $position and returned 0")
return 0
}
companion object{
private const val ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#"
private val DIFFER = object :DiffUtil.ItemCallback<String>(){
override fun areItemsTheSame(oldItem: String, newItem: String) = oldItem == newItem
override fun areContentsTheSame(oldItem: String, newItem: String) = oldItem.contentEquals(newItem)
}
fun logger(s:String){
Log.e("ALPHA", s )
}
}
}
Hello. I am trying to find a way by which it could work with a list adapter or with a regular recycler adapter but updating the mappings when list content is updated. currently the mappings remain the same and it causes a crash. can you help?
Here is my list adapter file :