1

I have implemented RecyclerView with changing backround when clicked on an item. RecyclerView contains only TextView. Sometimes when I click on an item the recyclerview scroll little bit. Strange is, that recyclerview behave like this, sometimes is everything OK. I am not sure why the RV is acting like this.

Direct link to gif - Action on RecyclerView

This is my Adapter

    private var selectedItemPosition: Int = 0
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PolozkaViewHolder {
        val binding = PolozkyItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return PolozkaViewHolder(binding)
    }
    override fun onBindViewHolder(holder: PolozkaViewHolder, position: Int) {
        val currentItem = getItem(position)
        holder.bind(currentItem)
      
        if (selectedItemPosition == position){
            holder.itemView.setBackgroundColor(Color.parseColor("#DA745A"))
        } else
        {
            holder.itemView.setBackgroundColor(Color.TRANSPARENT)
        }
    }
    inner class PolozkaViewHolder(private val binding: PolozkyItemBinding): RecyclerView.ViewHolder(binding.root){
        init {
            binding.root.setOnClickListener{
                val position = bindingAdapterPosition
                if (position != RecyclerView.NO_POSITION){
                    val item = getItem(position)
                    if (item != null){
                        listener.onItemClick(item, position)
                        //listener.onItemClickListener(item, position)
                    }
                }
                notifyItemChanged(selectedItemPosition)
                selectedItemPosition = absoluteAdapterPosition
                notifyItemChanged(selectedItemPosition)
            }
            binding.root.setOnLongClickListener{
                val positionLong = bindingAdapterPosition
                if (positionLong != RecyclerView.NO_POSITION){
                    val itemLong = getItem(positionLong)
                    if(itemLong != null){
                        listener.onLongClick(itemLong)
                    }
                }
                true
            }            
        }
        fun bind(polozkaPolozka: Polozka){
            binding.apply {
                tvStar.text =  if (polozkaPolozka.mnoz_vyd == 0.toFloat()){
                    ""
                }else (if (polozkaPolozka.mnoz_vyd != polozkaPolozka.mnoz_obj){
                                "-"
                            } else if (polozkaPolozka.mnoz_vyd == polozkaPolozka.mnoz_obj){
                                "*"
                            } else{
                                ""
                            })
                tvKDE.text = polozkaPolozka.znacky
                tvREG.text = polozkaPolozka.reg
                tvVB.text = polozkaPolozka.veb.toString()
                tvMN.text = polozkaPolozka.mnoz_obj.toString()
                tvMNV.text = polozkaPolozka.mnoz_vyd.toString()
                tvDATSPOTR.text = polozkaPolozka.datspo
                tvSARZE.text = polozkaPolozka.sarze

            }
        }        
    }
    interface OnItemClickListener{
        fun onItemClick(polozkaDoklad: Polozka, position: Int)
        fun onLongClick(polozkaDoklad: Polozka) 
    }
    class DiffCallback: DiffUtil.ItemCallback<Polozka>(){
        override fun areItemsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem.pvp06pk == newItem.pvp06pk
        override fun areContentsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem == newItem
    }
}

And this is my simple Activity

class PolozkaActivity: AppCompatActivity(), PolozkaAdapter.OnItemClickListener{
      override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      val binding = ActivityPolozkaBinding.inflate(layoutInflater)
    }

    override fun onItemClick(polozkaDoklad: Polozka, position: Int) {
        val resultReg = polozkaViewModel.getInfoByREG(polozkaDoklad.reg.toString())
        textViewStatus.text = "$resultReg"
        positionItem = position
    }

    override fun onLongClick(polozkaDoklad: Polozka) {
        val intent = Intent(this, NewActivity::class.java)
        startActivity(intent)
    }
}    

EDIT: Change of url of gif.

jenik2205
  • 445
  • 1
  • 5
  • 19
  • Have you tried on other devices? Zebra doesn't have the best screens, you may be moving your finger very slightly up, which when combined with that looks like a scroll to the OS. – Gabe Sechan Nov 17 '21 at 15:23
  • Have a look [here](https://stackoverflow.com/questions/43182601/android-how-to-disable-recyclerview-auto-scroll-from-clicking) – Zain Nov 17 '21 at 15:35
  • @GabeSechan I tried it on other device. Actually I think this is not problem of Zebra screen. – jenik2205 Nov 17 '21 at 15:35

1 Answers1

1

ViewHolder.absoluteAdapterPosition returns the position of the root view in pixels relative to the RecyclerView. It has nothing to do with the index of the associated item in the list.

I think the simplest way to fix what you have is to add a var currentIndex: Int property to your ViewHolder, and set that position in onBindViewHolder. Then change

            notifyItemChanged(selectedItemPosition)
            selectedItemPosition = absoluteAdapterPosition
            notifyItemChanged(selectedItemPosition)

to

            notifyItemChanged(selectedItemPosition)
            selectedItemPosition = currentIndex
            notifyItemChanged(selectedItemPosition)
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Please, can you help me how (and where) to add var currentIndex exactly. I am just beginner. Thanks – jenik2205 Nov 17 '21 at 15:48
  • Immediately after the `inner class PolozkaViewHolder` line, put a line `var currentIndex = 0`. In `onBindViewHolder()` you should add a line with `holder.currentIndex = position`. – Tenfour04 Nov 17 '21 at 16:28
  • Where is `bindingAdapterPosition` defined? It seems like it is already the same thing that I called `currentIndex`, but I'm not familiar with that property. – Tenfour04 Nov 17 '21 at 16:33