构建开发环境 构建demo_开发人员在构建RecyclerView时常犯的错误以及如何使用“ ViewRepresentation”类进行修复...

本文探讨了在构建RecyclerView时常见的错误及解决方法,通过提前计算值后的条件,而非在onBindViewHolder()中处理,以提高列表滚动性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构建开发环境 构建demo

When creating RecyclerView lists, we usually encounter list items that have the same ViewHolder but the values inside it are subject to different conditions.

创建RecyclerView列表时,我们通常会遇到具有相同ViewHolder的列表项,但其中的值受不同条件的影响。

Let’s say we’re building a list that displays invoices in a card view. Each item in the list has these conditions:

假设我们正在建立一个清单,在卡片视图中显示发票。 列表中的每个项目都具有以下条件:

For unpaid invoice:

对于未付款的发票:

  1. Displays “Unpaid” label at the top right corner of the card view

    在银行卡视图的右上角显示“未付款”标签
  2. Displays “Pay” button at the bottom of the card view

    在卡视图的底部显示“付款”按钮
  3. Displays due date in “dd-MM-yyyy” format

    以“ dd-MM-yyyy”格式显示到期日

For paid invoice:

对于已付款的发票:

  1. Displays “Paid” label at the top right corner of the card view

    在即时贴视图的右上角显示“付费”标签
  2. Displays “View” button at the bottom of the card view

    在卡片视图的底部显示“视图”按钮
  3. Displays due date in “dd-MM-yyyy” format

    以“ dd-MM-yyyy”格式显示到期日

Let’s use this minimal example just for this article.

让我们仅将此简单示例用作本文。

常见的错误 (Common Mistake)

The common mistake I usually notice with some developers is they handle these conditions inside the adapter’s onBindViewHolder() method like this:

我通常会与一些开发人员一起注意到的常见错误是,他们在适配器的onBindViewHolder()方法中处理这些条件,如下所示:

private val dateFormatter = SimpleDateFormat("dd-MM-yyyy")
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item: Invoice = getItem(position) if (item.status == PAID) {
holder.status.text = getString(R.string.paid)
holder.button.text = getString(R.string.view)
} else {
holder.status.text = getString(R.string.unpaid)
holder.button.text = getString(R.string.pay)
}

holder.dueDate.text = dateFormatter.format(invoice.dueDate)
}

Surely, this is fine for displaying short lists and for lists that only have those three conditions mentioned above. But, what if we’re displaying hundreds/thousands of items in the list with more conditions?

当然,这对于显示简短列表和仅具有上述三个条件的列表是很好的。 但是,如果我们在条件更多的列表中显示成百上千个项目怎么办?

This would cause onBindViewHolder() to repetitively run those conditions to bind the correct values to the views and the pain point is… poor scrolling performance.

这将导致onBindViewHolder()重复运行这些条件,以将正确的值绑定到视图,而痛点是……滚动性能差。

我对此 (My take on this)

As much as possible, the onBindViewHolder’s job should solely be for binding items to the list alone. All the conditions behind the values should be calculated beforehand.

尽可能的onBindViewHolder的工作应该仅仅是单独绑定表项的列表。 值后面的所有条件都应事先计算。

With this in mind, I have come up with this solution.

考虑到这一点,我想出了这个解决方案。

“ ViewRepresentation”类 (The “ViewRepresentation” Class)

ViewRepresentation is a class that is ready to be bound to the RecyclerView.

ViewRepresentation是一个可以绑定到RecyclerView的类。

This class should already contain the correct values so that the onBindViewHolder()'s job is solely for binding those values to the list.

该类应该已经包含正确的值,以便onBindViewHolder()的工作仅用于将这些值绑定到列表。

So, how should this look like using our example?

那么,使用我们的示例应该如何?

Image for post
InvoiceViewRepresentation.kt
InvoiceViewRepresentation.kt

So what is this class doing? Let’s break them down below:

那这个班在做什么? 让我们将它们分解如下:

  1. It has 3 fields statusText, buttonText, and dueDateText. These three fields should already contain the correct values to be displayed in the list.

    它具有3个字段statusTextbuttonTextdueDateText 。 这三个字段应该已经包含要在列表中显示的正确值。

  2. fromInvoice() utility method. This method should transform Invoice into its ViewRepresentation equivalent. This is where we run all the necessary conditions and set them ready for the list.

    fromInvoice()实用程序方法。 此方法应将Invoice转换为其等效的ViewRepresentation 。 这是我们运行所有必要条件并为列表准备的条件。

更新了onBindViewHolder()方法 (Updated onBindViewHolder() method)

Now that we already have our ViewRepresentation class for our Invoice list. Our onBindViewHolder() method should now look like this.

现在,我们已经为发票清单添加了ViewRepresentation类。 我们的onBindViewHolder()方法现在应如下所示。

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item: InvoiceViewRepresentation = getItem(position) holder.status.text = item.statusText
holder.button.text = item.buttonText
holder.dueDate.text = item.dueDateText
}

We have met our goal to make onBindViewHolder()’s only job is to bind the values to the view. That’s how it should be!

我们已经实现了使onBindViewHolder()唯一的工作就是将值绑定到视图的目标。 那应该是这样!

We have successfully eliminated repetitively doing the following while scrolling through the list:

我们已成功消除了在滚动列表时重复进行的以下操作:

  1. Running the if (status == PAID) condition

    运行if (status == PAID)条件

  2. Calling dateFormatter.format()

    调用dateFormatter.format()

And, this should result in a better performant RecyclerView!

并且,这应该导致性能更好的RecyclerView!

基本上就是这样! (And that’s basically it!)

I have been using this approach for quite a while now and have no problems with it so far.

我已经使用这种方法已有相当长的时间了,到目前为止还没有问题。

Also, it is very convenient especially when the “Invoice” is bound into different screens in your app. You can just reuse the same InvoiceViewRepresentation class and ensure its values are calculated consistently throughout different screens.

此外,这非常方便,尤其是当“发票”绑定到应用程序中的不同屏幕时。 您可以重复使用相同的InvoiceViewRepresentation类,并确保在不同屏幕上一致地计算其值。

I hope this can help someone build better performant lists.

我希望这可以帮助某人建立更好的绩效列表。

Thank you for reading!

感谢您的阅读!

翻译自: https://medium.com/@jermainedilao/common-mistake-developers-make-when-building-recyclerviews-and-how-to-fix-it-using-3b642a2ba0f4

构建开发环境 构建demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值