2016-09-22 76 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

不,这不是 - 这是中间解决的是我的适配器和回收站视图之间的类... –