如何解决RecyclerView.适配器的问题?



我试图改变列表中的第一个文本(位置= 0)重力'onBindViewHolder(viewHolder: viewHolder, position: Int)',但是,除了第一,一些元素的重力改变。你能告诉我这个问题是怎么来的吗?

你可以看到下面的代码和日志

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行将"回收";它显示自己(这就是为什么它被称为回收视图)。

如果你想要一个不同的第一行,尝试重写方法int getItemViewType(int position),并指定第一项是"不同的类型"。From the rest

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

ReyclerViews有一些ViewHolders,他们交换,使其看起来像一个大列表,但实际上它是相同的几个盒子骑沿着传送带,被移动从结束回到开始。

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

但是我希望这能让更广泛的观点更清晰——当你绑定项时,你总是需要用RecyclerViews做这些事情,因为你重用了用旧数据和旧状态填充的旧项。因此,每次都应该对它们进行完整的配置,以应对可能发生的任何变化。你不会想要任何旧的状态!

(Luiz的回答也是一个很好的选择,有一个完全独立的项目类型的标题允许你使用不同的ViewHolder与自己的布局等,所以没有必要保持重新配置一个单一的布局。但是,如果你只是做一个小的改变,这可能是太多的工作-你有选择!)

相关内容

  • 没有找到相关文章

最新更新