2017-04-14 37 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

你的回答是對的,但第二個代碼示例,並會更加欣賞社區。 非常感謝!你是對的,你救了我幾個小時,我想:) –