单击项目Android时RecyclerView滚动

Posted

技术标签:

【中文标题】单击项目Android时RecyclerView滚动【英文标题】:RecyclerView scrolls when click on item Android 【发布时间】:2021-12-28 13:04:41 【问题描述】:

我已经实现了 RecyclerView,当点击一个项目时会改变背景。 RecyclerView 仅包含 TextView。有时当我点击一个项目时,recyclerview 会滚动一点。奇怪的是,recyclerview 的行为是这样的,有时一切正常。我不知道为什么 RV 会这样。

直接链接到 gif - Action on RecyclerView

这是我的适配器

    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
    

这是我的简单活动

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)
    
    

编辑:更改 gif 的网址。

【问题讨论】:

你在其他设备上试过了吗? Zebra 没有最好的屏幕,您的手指可能会稍微向上移动,与此结合起来看起来就像是滚动到操作系统。 看看here @GabeSechan 我在其他设备上试过了。其实我觉得这不是斑马屏的问题。 【参考方案1】:

ViewHolder.absoluteAdapterPosition 返回根视图相对于 RecyclerView 的位置(以像素为单位)。它与列表中关联项的索引无关。

我认为解决问题的最简单方法是将var currentIndex: Int 属性添加到您的ViewHolder,并将该位置设置为onBindViewHolder。然后改变

            notifyItemChanged(selectedItemPosition)
            selectedItemPosition = absoluteAdapterPosition
            notifyItemChanged(selectedItemPosition)

            notifyItemChanged(selectedItemPosition)
            selectedItemPosition = currentIndex
            notifyItemChanged(selectedItemPosition)

【讨论】:

拜托,你能帮我如何(以及在​​哪里)准确地添加 var currentIndex。我只是初学者。谢谢 inner class PolozkaViewHolder 行之后,添加一行var currentIndex = 0。在onBindViewHolder() 中你应该添加一行holder.currentIndex = position bindingAdapterPosition 在哪里定义?似乎它已经是我称之为currentIndex 的东西了,但我对那个属性并不熟悉。

以上是关于单击项目Android时RecyclerView滚动的主要内容,如果未能解决你的问题,请参考以下文章

在Android recyclerVIew中单击项目时如何保存状态

Android - 在 RecyclerView 中单击的项目上打开新活动 [重复]

Recyclerview 项目在再次获取数据时增加高度 Android Kotlin

RecyclerView 动画问题 Android Kotlin

如何让 Espresso 单击特定的 RecyclerView 项目?

获取所选recyclerView项目android的ID