RecyclerView在幕后是如何工作的?

huangapple go评论92阅读模式
英文:

How does the RecyclerView work behind the scenes?

问题

For several years, I have been using RecyclerView in different apps, but I did not fully understand its underlying functioning. Nonetheless, I now have a better comprehension of how RecyclerView works after reading tutorial articles such as this one and this one.

Before reading these articles, I had an incorrect understanding of RecyclerView, which I can explain with an example. Let's say we have a simple item in RecyclerView, and in the onBindViewHolder method, we want to change the color of the TextView to black only if the position equals zero; otherwise, it should take the default color set to white in the XML.

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textview.MaterialTextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/txt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#ffffff" />
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {

    if (position == 0)
        holder.row.txt.setTextColor(Color.BLACK);

}

However, I noticed that while scrolling in RecyclerView, some TextViews also changed to black even if their position was not zero. Online solutions recommended using an Else-Clause with an If-Clause, but I doubted its necessity. I believed that if the If-Clause didn't execute, then the default color set to white in the XML would be used. Yet, some TextViews still took on the black color even if the item position was not equal to zero.

To understand why I needed to add an Else-Clause with If-Clause, I researched how RecyclerView works behind the scenes. After reading the articles, I finally understood why.

Here's how RecyclerView works behind the scenes using a real-life example: Imagine opening a small restaurant for the first time. You need to buy a tray from a furniture store to put in your restaurant - the tray with its original design and no modifications.

This is similar to onCreateViewHolder, where RecyclerView creates a new view from the original layout without any modifications, just like how you bought a new tray without any changes because it was new.

The first customer who comes to the restaurant uses the new tray to eat his breakfast and sees the tray in its new condition. But before leaving, he accidentally damages part of the tray.

Hours later, the second customer arrives and uses the same tray. Although he orders a different breakfast, he will see the tray with the damage because the first customer caused it.

This is similar to onBindViewHolder, where the data inside the TextView is the breakfast, and the text color is the part of the tray that's damaged because the tray became used.

Hours later, the third customer arrives and uses the same tray. He also orders a different breakfast and sees the tray with the damage, but he doesn't like it, and before leaving the restaurant, he destroys the tray.

Now, we need to go back to the furniture store and buy a new tray.

This is like onCreateViewHolder when failed to bind data for any reason; it will re-create a new view.

The fourth customer who comes will see the new tray without any damage.

I hope I have conveyed the example clearly.

Now, my question is, does RecyclerView work this way, or have I misunderstood something?

英文:

For several years, I have been using RecyclerView in different apps, but I did not fully understand its underlying functioning. Nonetheless, I now have a better comprehension of how RecyclerView works after reading tutorial articles such as this one and this one.

Before reading these articles, I had an incorrect understanding of RecyclerView, which I can explain with an example. Let's say we have a simple item in RecyclerView, and in the onBindViewHolder method, we want to change the color of the TextView to black only if the position equals zero; otherwise, it should take the default color set to white in the XML.

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;com.google.android.material.textview.MaterialTextView
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/txt&quot;
    android:layout_width=&quot;wrap_content&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:textColor=&quot;#ffffff&quot; /&gt;

---

@Override
public void onBindViewHolder(@NonNull VH holder, int position) {

    if (position == 0)
        holder.row.txt.setTextColor(Color.BLACK);

}

However, I noticed that while scrolling in RecyclerView, some TextViews also changed to black even if their position was not zero. Online solutions recommended using an Else-Clause with an If-Clause, but I doubted its necessity. I believed that if the If-Clause didn't execute, then the default color set to white in the XML would be used. Yet, some TextViews still took on the black color even if the item position was not equal to zero.

To understand why I needed to add an Else-Clause with If-Clause, I researched how RecyclerView works behind the scenes. After reading the articles, I finally understood why.

Here's how RecyclerView works behind the scenes using a real-life example: Imagine opening a small restaurant for the first time. You need to buy a tray from a furniture store to put in your restaurant - the tray with its original design and no modifications.

This is similar to onCreateViewHolder, where RecyclerView creates a new view from the original layout without any modifications, just like how you bought a new tray without any changes because it was new.

The first customer who comes to the restaurant uses the new tray to eat his breakfast and sees the tray in its new condition. But before leaving, he accidentally damages part of the tray.

Hours later, the second customer arrives and uses the same tray. Although he orders a different breakfast, he will see the tray with the damage because the first customer caused it.

This is similar to onBindViewHolder, where the data inside the TextView is the breakfast, and the text color is the part of the tray that's damaged because the tray became used.

Hours later, the third customer arrives and uses the same tray. He also orders a different breakfast and sees the tray with the damage, but he doesn't like it, and before leaving the restaurant, he destroys the tray.

Now, we need to go back to the furniture store and buy a new tray.

This is like onCreateViewHolder when failed to bind data for any reason; it will re-create a new view.

The fourth customer who comes will see the new tray without any damage.

I hope I have conveyed the example clearly.

Now, my question is, does RecyclerView work this way, or have I misunderstood something?

答案1

得分: 1

TextView 的颜色变成黑色,即使它们的位置不是零,是因为视图回收。当一个 ItemView 滚动出屏幕时,RecyclerView 会重新使用该视图来显示新可见的项,而不是从头开始创建一个新的视图/布局,因为为每个项创建新的布局/视图是昂贵的。

所以,当你将位置零的文本颜色设置为黑色时,与位置零关联的 View 将正确更新文本颜色。

然而,当该视图被回收以用于不同位置(比如第8或第10个位置的项)时,如果你不显式将文本颜色重新设置为默认颜色(在你的情况下为白色),则回收的视图将保留先前绑定的黑色文本颜色。

英文:

The TextViews changing to black color even when their position was not zero is due to view recycling.
When an ItemView scrolls off the screen, the RecyclerView reuses that view for a newly visible item, rather than creating a new view from scratch as creating a new layout / view for every item is expensive.

So, when you set the text color to black for position zero,
the View associated with position zero will have the text color updated correctly.

However, when that view is recycled for a different position (say 8th or 10th position item), if you don't explicitly set the text color back to the default color (white in your case), the recycled view will retain the black text color from the previous binding.

huangapple
  • 本文由 发表于 2023年5月13日 18:30:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76242246.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定