【问题标题】:RecyclerView item's image bugRecyclerView 项目的图像错误
【发布时间】:2017-04-14 15:01:18
【问题描述】:

问题:RecyclerView 的子项 ImageView 出现故障错误

我有一个 RecyclerView。每个项目都有 ID 为“like”的 ImageView,它基本上是一个空星。

当我们点击某个项目的“Like”时,例如第一个,星号从空的变成黄色,表示该项目被点赞。

当我们点击第一项时,一切正常,一切都应该是,但同时,我们有一个错误,将第六项的“喜欢”更改为实心星,这是不应该做的,因为这个项目还没有被喜欢。

如果我们点击第二个项目的点赞 - 第七个项目会有同样的错误。

要填充 ViewHolder 中的项目,我有一个模型 - 食谱。

open class Recipe constructor(open var label: String,

                          open var image: String,

                          open var url: String,

                          open var ingredients: RealmList<Ingredient>?,

                          open var calories: Float,

                          open var totalWeight: Float,

                          open var id: Int,

                          open var isFavorite: Boolean) : RealmObject() 

所以当点击某个项目时,我会检查它是否是收藏夹,并相应地更改“喜欢”的 ImageView。

有人知道我应该如何解决这个问题吗?

我尝试关闭适配器中的项目回收,但不幸的是,在这种情况下,“喜欢”状态也没有保存。

“喜欢”按钮的 OnClick 监听器

itemView.like.onClick {
                if (recipe.isFavorite) {
                    itemView.like.image = ContextCompat.getDrawable(itemView.context, R.drawable.ic_star_before_like)
                    recipe.isFavorite = false
                    DatabaseService.removeRecipeFromFavorites(recipe)
                    itemView.context.toast("Recipe removed from favorites.")
                } else {
                    itemView.like.image = ContextCompat.getDrawable(itemView.context, R.drawable.ic_star_after_like)
                    recipe.isFavorite = true
                    DatabaseService.addNewFavoriteRecipe(recipe)
                    itemView.context.toast("Recipe added to favorites.")
                }

            }

XML 文件

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="0dip"
  android:layout_weight="0.8"
  android:gravity="center|right"
  android:orientation="horizontal">

  <ImageView
    android:id="@+id/like"
    android:layout_width="@dimen/icon_size_card"
    android:layout_height="@dimen/icon_size_card"
    android:padding="5dp"
    android:layout_marginRight="@dimen/icon_margin_card"
    android:src="@drawable/ic_star_before_like" />

  <ImageView
    android:id="@+id/share"
    android:layout_width="@dimen/icon_size_card"
    android:layout_height="@dimen/icon_size_card"
    android:padding="5dp"
    android:layout_marginRight="@dimen/icon_margin_card"
    android:src="@drawable/ic_share" />

  <ImageView
    android:id="@+id/save"
    android:layout_width="@dimen/icon_size_card"
    android:layout_height="@dimen/icon_size_card"
    android:padding="5dp"
    android:layout_marginRight="@dimen/icon_margin_card"
    android:src="@drawable/ic_save_recipe" />

  <ImageView
    android:id="@+id/expand"
    android:layout_width="@dimen/icon_size_card"
    android:layout_height="@dimen/icon_size_card"
    android:padding="5dp"
    android:layout_marginRight="@dimen/icon_margin_card"
    android:src="@drawable/ic_down_arrow" />

</LinearLayout>

【问题讨论】:

    标签: java android xml jvm kotlin


    【解决方案1】:

    RecyclerView 重用它用onCreateViewHolder 创建的视图。简而言之,将其视为顶部离开屏幕的视图又回到底部,反之亦然。因此,解决您想要的问题的好方法如下:

    1. 在onBindViewHolder 方法中将图标设置为可绘制的右侧。这样,无论是第一次绑定一个视图,还是已经有一个反映配方最喜欢状态的可绘制对象,它都会被正确刷新。

      在不知道你的适配器是什么样子的情况下,这应该让你知道如何做到这一点(示例代码假设你的食谱在某个名为 recipes 的列表中):

      override fun onBindViewHolder(holder: ViewHolder, position: Int) {
          val recipe = recipes[position]
          val itemView = holder.itemView
          itemView.like.image = ContextCompat.getDrawable(itemView.context,
                  if(recipe.isFavorite) R.drawable.ic_star_before_like else R.drawable.ic_star_after_like)
      }
      
    2. 在侦听器中,修改Recipe,方法与现在相同,但不是直接设置图像,而是通知适配器给定位置的配方已更改(notifyItemChanged(position) ),这将使它重新绑定该项目,刷新图标以反映新状态。同样,我不知道你在哪里设置监听器,但我假设你知道配方在列表中的位置。

    【讨论】:

      【解决方案2】:

      RecyclerView 用于缓存视图并重用它们。当您滚动时,您的视图会被回收并从内存中加载。

      对附加到适配器的基础数据模型进行更改后,通知适配器同样重要。在您的 onClick 方法中,进行更改后,请确保您调用 adapter.notifyDataSetChanged(),如果您直接从适配器类调用它,请确保调用 notifyDataSetChanged()。

      【讨论】:

      • 您的回答也是正确的,但第二个有代码示例,社区会更感激。十分感谢!你是对的,我猜你为我节省了几个小时:)
      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2021-09-04
      相关资源
      最近更新 更多