繁体   English   中英

如何解决 RecyclerView.Adapter 问题?

[英]How to solve RecyclerView.Adapter issue?

我试图从'onBindViewHolder(viewHolder:ViewHolder,位置:Int)'中的List更改第一个文本(位置= 0)重力,但是,除了第一个,某些元素的重力发生了变化。 你能告诉我这个问题是从哪里来的吗?

您可以在下面查看代码以及日志

class ButtonsListAdapter(private val dataSet: List<String>) :
    RecyclerView.Adapter<ButtonsListAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView
        val divider: View

        init {
            textView = view.findViewById(R.id.textView)
            divider = view.findViewById(R.id.divider)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(viewGroup.context)
            .inflate(R.layout.buttons_list_item, viewGroup, false)

        return ViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        viewHolder.textView.text = dataSet[position]
        if(position == 0) {
            Log.i("Position", " position ->  $position ")
            viewHolder.textView.gravity = Gravity.START or Gravity.CENTER_VERTICAL
        }
        Log.i("Position", " gravity ->  $position " + viewHolder.textView.gravity)
    }

    override fun getItemCount() = dataSet.size
}

日志

I/Position:  position ->  0 
I/Position:  gravity ->  0 8388627
I/Position:  gravity ->  1 17
I/Position:  gravity ->  2 17
I/Position:  gravity ->  3 17
I/Position:  gravity ->  4 17
I/Position:  gravity ->  5 17
I/Position:  gravity ->  6 17
I/Position:  gravity ->  7 17
I/Position:  gravity ->  8 17
I/Position:  gravity ->  9 8388627
I/Position:  gravity ->  10 17
I/Position:  gravity ->  11 17
I/Position:  gravity ->  12 17
I/Position:  gravity ->  13 17
I/Position:  gravity ->  14 17
I/Position:  gravity ->  15 17
I/Position:  gravity ->  16 17
I/Position:  gravity ->  17 17
I/Position:  gravity ->  9 8388627
I/Position:  gravity ->  8 17
I/Position:  gravity ->  7 17
I/Position:  gravity ->  6 17
I/Position:  gravity ->  5 17
I/Position:  gravity ->  4 17
I/Position:  gravity ->  3 17
I/Position:  gravity ->  2 17
I/Position:  gravity ->  1 17
I/Position:  position ->  0 
I/Position:  gravity ->  0 8388627

我相信 RecyclerView 尝试使用旧行来节省内存使用量。 这有点像:当视图 0 出现在屏幕上时,新的第 9 行将“回收”它以显示自己(这就是它被称为 RecyclerView 的原因)。

如果您想要不同的第一行,请尝试覆盖方法int getItemViewType(int position)并指定第一个项目是与其余项目“不同的类型”

(或者你可以在if(position == 0)上添加一个 else 并强制你想要的重力,但我认为另一个选项更优雅)

ReyclerView有一些ViewHolder ,它们交换它们以使其看起来像一个大列表,但实际上它是沿着传送带移动的相同的几个盒子,从末端移回开始。

onBindViewHolder是您设置其中一个框的内容以在列表中的该位置显示项目的位置。 提供给您的ViewHolder看起来仍然与设置为显示前一个项目时一样,因此您需要确保为新项目正确设置了所有内容 您不更改的任何内容都会在上面,看起来就像它显示的最后一个项目。

所以这是你的问题:

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
    viewHolder.textView.text = dataSet[position]
    if(position == 0) {
        viewHolder.textView.gravity = Gravity.START or Gravity.CENTER_VERTICAL
    }
}

项目之间变化的部分显示状态是重力 - 在这里您将其设置为项目 0 ,但您没有将其设置为其他项目的正常状态。 它很,你只能设置一种方式,它永远不会恢复。 因此,需要在该回收的ViewHolder对象中显示的下一个项目将具有相同的重力设置,因为这就是它的设置! 哪个是您的日志中的第9 项(您可以看到在重用开始时创建了多少ViewHolder - 看起来在这种情况下碰巧使用了其中的 9 个)


所以,是的,您需要在所有情况下设置重力 - 为每个项目设置整个显示状态,以确保它是一致的,并且旧状态都不会影响它现在的外观:

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
    viewHolder.textView.text = dataSet[position]
    // explicitly set the gravity every time
    if(position == 0) {
        viewHolder.textView.gravity = Gravity.START or Gravity.CENTER_VERTICAL
    } else {
        viewHolder.textView.gravity = // whatever
    }
}

但我希望这能让更广泛的观点更清楚——当你绑定项目时,你总是需要用RecyclerView来做这些事情,因为你正在重用填充了旧数据和旧状态的旧项目。 因此,您应该每次都完全配置它们,以应对可能发生的任何变化。 您不希望任何旧状态徘徊!

(Luiz 的回答也是一个不错的选择,为标题提供完全独立的项目类型允许您使用具有自己布局等的不同ViewHolder ,因此无需继续重新配置单个布局。但如果你正在做一个小改变 - 你有选择!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM