如何求解recyclerview.apter问题?
我正在尝试将第一个文本(位置= 0)的重力从'onBindViewHolder(Viewholder:View Holder,位置: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
I am trying to change first text(position = 0) gravity from List in 'onBindViewHolder(viewHolder: ViewHolder, position: Int)', but, except for the first, the gravity of some elements changes. Could you tell me where this problem comes from?
You can see code below and also logs
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
}
Logs
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信Recyclerview试图使用旧行来节省内存使用情况。
有点像:当视图0熄灭屏幕时,新行9将“回收”它以显示自身(为什么称为RecyClerview)。
如果需要不同的第一行,请尝试覆盖方法
int getItemViewType(int position)
,并指定第一个项目是与其他项目的“不同类型”(或者您只需在<<代码> if(位置== 0)并强制您想要的重力,但我认为另一种选择更优雅)
I believe the RecyclerView tries to use old rows to save on memory usage.
It's kinda like: when the view 0 goes out the screen, the new line 9 will "recycle" it to show itself (that why it's called RecyclerView).
If you want a different first line, try override the method
int getItemViewType(int position)
and specify that the first item is a "different type" from the rest(or you could just add an else on
if(position == 0)
and force the gravity you want, but I think the other option is more elegant)reyclerview
s有几个view holder
s,它们交换以使其看起来像一个大列表,但实际上它是沿着传送带骑行的几个盒子,被移动了从末端回到开始。OnBindViewHolder
是您设置其中一个框的内容以显示列表中该位置的项目。您为您提供的Viewholder
在设置以显示以前的项目时看起来仍然像它一样,因此您需要确保正确设置所有内容新的。您不更改的任何东西,都会 stick ,看起来就像它显示的最后一项。因此,这是您的问题:
显示项目之间的变化是重力的一部分 - 在这里,您将其设置为 item 0 ,但您并未将其设置为其他项目的正常情况。它是粘性,您只将其设置为一种方式,并且永远无法恢复。因此,需要在该回收的
View> view holder
对象中显示的下一个项目将具有相同的重力设置,因为那是设置的!这是项目9 通过日志进行(您可以看到重复使用启动时会创建多少view> viewholder
- 看起来恰好在此中使用了其中的9个案例)是的,是的,您需要在所有情况下设置重力 - 设置每个项目的整个显示状态,以确保其一致,并且没有一个旧状态可以影响现在的外观:
但是我希望这使得更加清晰 - 您始终需要在绑定项目时使用
recyclerview
s进行此操作,因为您正在重用填充的旧项目使用旧数据和旧状态。因此,您应该每次完全配置它们,以获取任何可能改变的东西。您不希望任何旧州闲逛!(Luiz的答案也是一个不错的选择,拥有一个完全独立的项目类型的标题类型允许您使用自己的布局等使用其他
View -Codeholder
,因此无需继续重新配置单个布局。如果您要进行较小的更改,可能会做得太多 - 您有选择!)ReyclerView
s have a handful ofViewHolder
s that they swap around to make it look like a large list, but really it's the same few boxes riding along a conveyor belt, being moved from the end back to the start.onBindViewHolder
is where you set the contents of one of those boxes to display the item at that position in the list. TheViewHolder
that you're provided with still looks like it did when it was set up to display a previous item, so you need to make sure everything is set up correctly for the new one. Anything you don't change, will stick and look like the last item it was displaying.So here's your problem:
Part of the display state that changes between items is the gravity - and here you're setting it for item 0, but you're not setting it to normal for the other items. It's sticky, you only set it one way, and it can never revert. So the next item that needs to display in that recycled
ViewHolder
object will have that same gravity setting, because that's what it's been set to! Which is item 9 going by your logs (you can see how manyViewHolder
s are getting created by when the reuse starts - looks like it happens to use 9 of them in this case)So yeah, you need to set the gravity in all cases - set the whole display state for every item, to ensure it's consistent and that none of the old state can influence how it looks now:
But I hope that makes the broader point clearer - you always need to do this stuff with
RecyclerView
s when you're binding items, because you're reusing old items that are filled in with old data and old state. So you should fully configure them each time, for anything that could potentially change. You don't want any old state hanging around!(Luiz's answer is also a good option, having a completely separate item type for a header allows you to use a different
ViewHolder
with its own layout etc, so there's no need to keep reconfiguring a single layout. But it might be too much work if you're making a small change - you have options!)