2017-04-14 48 views
0

问题:与RecyclerView的孩子的项目ImageView的RecyclerView项目的图像错误

毛刺错误我有一个RecyclerView.Each项目与ID 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() 

等一些项目,当点击我检查它是否isFavorite与否,并相应地改变了“喜欢”的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> 

回答

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)),这将使其重新绑定该项,刷新该图标反映了新的状态。再次,我不知道你在哪里设置听众,但我想你知道配方在列表中的位置。

1

RecyclerView内置缓存的意见和重用他们。当您滚动时,您的视图将被回收并从内存中加载。

对连接到适配器的基础数据模型进行了更改后,请务必通知适配器。在您的onClick方法中,在做出更改后,如果您直接从适配器类中调用它,请确保您致电adapter.notifyDataSetChanged()或仅notifyDataSetChanged()

+1

你的回答是对的,但第二个代码示例,并会更加欣赏社区。 非常感谢!你是对的,你救了我几个小时,我想:) –