RecyclerView项目的图像错误

时间:2017-04-14 15:01:19

标签: java android xml jvm kotlin

问题:使用RecyclerView的子项目ImageView

出现故障

我有一个RecyclerView.Each项目有ImageView,ID为#34;喜欢"这基本上是一颗空星。

当我们点击某个项目"喜欢",例如,第一个,明星正在从填充黄色的空白变化,这意味着该项目是喜欢的。

当我们点击第一项时一切正常,一切都是应有的,但与此同时,我们有一个错误,改变第六项" s"喜欢"对于一个不应该完成的明星,因为这个项目还没有被喜欢。

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

要在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() 

因此,当点击某个项目时,我会检查它是否是最喜欢的,并更改&#34;喜欢&#34;相应的ImageView。

有人有任何想法我应该如何解决这个问题吗?

我试图关闭适配器中的项目回收,但不幸的是,在这种情况下,&#34;喜欢&#34;国家也没有得救。

OnClick侦听器&#34;喜欢&#34;按钮

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>

2 个答案:

答案 0 :(得分:1)

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

对附加到适配器的基础数据模型进行更改后,务必通知适配器。在onClick方法中,完成更改后,如果您直接从适配器类调用它,请务必致电adapter.notifyDataSetChanged()notifyDataSetChanged()

答案 1 :(得分:1)

onCreateViewHolder重复使用onBindViewHolder创建的视图。简单来说,把它看作是顶部屏幕上的视图从底部返回,而反之亦然。因此,解决问题的好方法如下:

  1. recipes方法中将图标设置为右侧drawable。这样,无论视图是第一次被绑定,还是已经有一个反映出配方的受欢迎状态的drawable,它都会被正确刷新。

    在不知道你的适配器是什么样的情况下,这应该让你知道如何做到这一点(示例代码假设你在一些名为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) } 的列表中有你的食谱):

    Recipe
  2. 在监听器中,以与您现在相同的方式修改android:theme="@style/Theme.AppCompat.Light" ,但不是直接设置图像,而是通知适配器给定位置的配方已更改(notifyItemChanged(position)),它将重新绑定该项,刷新图标以反映新状态。再说一次,我不知道你在哪里设置听众,但我想你知道配方在那里的位置是什么位置。