2016-09-22 75 views
0

我有一個RecyclerView,滾動後,我的adapter中的項目值交換。這顯然是視圖回收的一個問題,基礎數據沒有被清除。RecyclerView弄亂指數

但是,我已經讀了幾十次這個問題的迭代,但我無法解讀任何答案的明確修復,並且我的問題仍然存在。

我設置Adapter有穩定的ID,覆蓋getItemgetItemIdgetItemCount方法,以及 - 我想 - 我onBindViewHolder法進行正確的檢查,以判斷我的數據是乾淨的還是不...但這最後一部分讓我感到困惑,因爲我不確定我應該執行什麼條件(我覺得這些問題的答案大部分都缺乏)...

下面是一些相關的代碼:

public class MenuQueryAdapter extends ParseRecyclerQueryAdapter<MenuItem, MenuQueryAdapter.MenuViewHolder> { 

    public MenuQueryAdapter(ParseQueryAdapter.QueryFactory<MenuItem> factory, boolean hasStableIds) { 
     super(factory, hasStableIds);// hasStableIds set to TRUE 
    } 


    @Override 
    public MenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     return new MenuViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_item, parent, false)); 
    } 

    @Override 
    public void onBindViewHolder(MenuViewHolder holder, int position) { 
     MenuItem menuItem = getItem(position); 
     holder.bindItem(menuItem); 
    } 

    @Override 
    public MenuItem getItem(int position) { 
     //return super.getItem(position); 
     if (menuItemList != null && menuItemList.size() > 0) { 
      return menuItemList.get(position); 
     } 
     return super.getItem(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 


    // View Holder 
    public static class MenuViewHolder extends RecyclerView.ViewHolder { 

     MenuItem menuItem; 

     TextView title; 
     TextView price; 
     TextView summary; 
     TextView itemCount; 

     TextView calorieLabel; 
     TextView proteinLabel; 
     TextView fatLabel; 
     TextView carbsLabel; 
     TextView fiberLabel; 

     ParseImageView imageView; 

     private String objectId = ""; 
     private boolean active = true; 
     private boolean inStock = true; 
     private boolean cSoon = false; 
     private boolean hasNutrition = false; 


     MenuViewHolder(View itemView) { 
      super(itemView); 

      title = (TextView) itemView.findViewById(R.id.menu_title_label); 
      price = (TextView) itemView.findViewById(R.id.menu_price_label); 
      summary = (TextView) itemView.findViewById(R.id.menu_summary); 

      calorieLabel = (TextView) itemView.findViewById(R.id.menu_label_calorie_value); 
      proteinLabel = (TextView) itemView.findViewById(R.id.menu_label_protein_value); 
      fatLabel = (TextView) itemView.findViewById(R.id.menu_label_fat_value); 
      carbsLabel = (TextView) itemView.findViewById(R.id.menu_label_carbs_value); 
      fiberLabel = (TextView) itemView.findViewById(R.id.menu_label_fibre_value); 

      imageView = (ParseImageView) itemView.findViewById(R.id.menu_main_image); 

      // Containers 
      final RelativeLayout activeView = (RelativeLayout) itemView.findViewById(R.id.menu_top_view_active); 
      final RelativeLayout inactiveView = (RelativeLayout) itemView.findViewById(R.id.menu_top_view_inactive); 

      View.OnClickListener clickListener = new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        active = !active; 
        if(active) 
        { 
         activeView.setVisibility(View.VISIBLE); 
         inactiveView.setVisibility(View.INVISIBLE); 
        } 
        else 
        { 
         activeView.setVisibility(View.INVISIBLE); 
         inactiveView.setVisibility(View.VISIBLE); 
        } 
       } 
      }; 

      final RelativeLayout topView = (RelativeLayout) itemView.findViewById(R.id.menu_top_view); 
      topView.setOnClickListener(clickListener); 

      final ImageButton info = (ImageButton) itemView.findViewById(R.id.menu_info_button); 
      info.setOnClickListener(clickListener); 

     } 

     public void bindItem(MenuItem item) { 
      menuItem = item; 

      menuItem.populateData(); // gets data from DB 

      // THIS IS MY CHECK TO SEE IF THE DATA SHOULD EB RECYCLED 
      if(!menuItem.getTitle().equals(enroot.getContext().getResources().getString(R.string.menu_title))) { 
       title.setText(menuItem.getTitle()); 
       price.setText(String.valueOf(menuItem.getPrice())); 
       summary.setText(menuItem.getSummary()); 
       calorieLabel.setText(menuItem.getCalories()); 
       proteinLabel.setText(menuItem.getProtein()); 
       fatLabel.setText(menuItem.getFat()); 
       carbsLabel.setText(menuItem.getCarbs()); 
       fiberLabel.setText(menuItem.getFibre()); 
       imageView.setParseFile(menuItem.getImage()); 
       imageView.loadInBackground(); 

       if (menuItem.getInt(EnrootConstants.kERItemInStockKey) <= 0) { 
        inStock = false; 
       } 
       if (menuItem.getBoolean(EnrootConstants.kERItemComingSoonKey) && inStock) { 
        cSoon = true; 
       } 
       if (menuItem.getList(EnrootConstants.kERItemNutritionKey) != null && menuItem.getList(EnrootConstants.kERItemNutritionKey).size() > 0) { 
        hasNutrition = true; 
       } 

       // Id 
       objectId = menuItem.getObjectId(); 
       if (mOnItemChangedListener != null) { 
        mOnItemChangedListener.passIdToActivity(objectId); 
       } 

       // Stock 
       RelativeLayout ooStock = (RelativeLayout) itemView.findViewById(R.id.menu_soldout); 
       if (!inStock) { 
        ooStock.setVisibility(View.VISIBLE); 
       } 

       // Coming Soon 
       RelativeLayout comingSoon = (RelativeLayout) itemView.findViewById(R.id.menu_comingsoon); 
       if (cSoon) { 
        comingSoon.setVisibility(View.VISIBLE); 
       } 

       // Nutrition 
       if (!hasNutrition) { 
        RelativeLayout nutritionOverlay = (RelativeLayout) itemView.findViewById(R.id.menu_nutrition_group); 
        nutritionOverlay.setVisibility(View.INVISIBLE); 
       } 

       // Minus 
       final ImageButton minus = (ImageButton) itemView.findViewById(R.id.menu_btn_minus); 
       if (inStock && !cSoon) { 
        minus.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          if (mOnItemChangedListener != null) { 
           mOnItemChangedListener.onPriceSubtracted(objectId, getAdapterPosition()); 
          } 
         } 
        }); 
       } else { 
        minus.setVisibility(View.INVISIBLE); 
        minus.setEnabled(false); 
        minus.setClickable(false); 
       } 

       // Plus 
       final ImageButton plus = (ImageButton) itemView.findViewById(R.id.menu_btn_plus); 
       if (inStock && !cSoon) { 
        plus.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          if (mOnItemChangedListener != null) { 
           mOnItemChangedListener.onPriceAdded(objectId, getAdapterPosition()); 
          } 
         } 
        }); 
       } else { 
        plus.setVisibility(View.INVISIBLE); 
        plus.setEnabled(false); 
        plus.setClickable(false); 
       } 
      } 
      else { 
       clearItem(); 
      } 
     } 

     void clearItem() { 

      title.setText(""); 
      price.setText(""); 
      summary.setText(""); 
      calorieLabel.setText(""); 
      proteinLabel.setText(""); 
      fatLabel.setText(""); 
      carbsLabel.setText(""); 
      fiberLabel.setText(""); 

      objectId = ""; 
      active = true; 
      inStock = true; 
      cSoon = false; 
      hasNutrition = false; 

     } 

    } /* eoc holder */ 

    } /* eoc adapter */ 

所以...我看到很多關於簡單覆蓋getItem和/或getItemId(如果您有穩定ID的情況下是有道理的),但這似乎沒有任何影響。我甚至在ViewHolder上將setIsRecyclable設置爲false,不起作用。

我卡住了...很想聽到的話,我做得極不正常...

+0

會轉而只隨時撥打clearItem如果你的標題條件失敗。同時檢查你的標題條件,看起來很奇怪,當前標題與靜態標題進行比較。 – nenick

+0

與靜態標題的比較是因爲我使用該字符串資源作爲XML視圖的文本 - 如果將其設置爲null,我將無法看到它,所以這是一個佔位符。所以這是代替!TextUtils.isEmpty()等 –

+0

所以...總是清楚嗎?那麼在什麼條件下我可以設置我的數據對象的值? –

回答

0

我想你錯過了返回的項目計數

@Override 
public int getItemCount() { 
    return menuItemList.size(); 
} 
+0

不,這不是 - 這是中間解決的是我的適配器和回收站視圖之間的類... –