Skip to content

Does not work with list adapter or after the list is updated #89

@sachdeva-tagic

Description

@sachdeva-tagic

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 )
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions