我试图改变列表中的第一个文本(位置= 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并强制你想要的重力,但我认为其他选择更优雅)
ReyclerView
s有一些ViewHolder
s,他们交换,使其看起来像一个大列表,但实际上它是相同的几个盒子骑沿着传送带,被移动从结束回到开始。
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
s做这些事情,因为你重用了用旧数据和旧状态填充的旧项。因此,每次都应该对它们进行完整的配置,以应对可能发生的任何变化。你不会想要任何旧的状态!
(Luiz的回答也是一个很好的选择,有一个完全独立的项目类型的标题允许你使用不同的ViewHolder
与自己的布局等,所以没有必要保持重新配置一个单一的布局。但是,如果你只是做一个小的改变,这可能是太多的工作-你有选择!)