【问题标题】:Recyclerview with multiple layouts duplicate items on scrolling具有多个布局的 Recyclerview 在滚动时重复项目
【发布时间】:2017-01-04 03:34:03
【问题描述】:

在具有多个布局的 Recyclerview 中,我重写了 getItemViewType() 方法,通过该方法我决定要显示哪个布局。滚动重复项目时出现奇怪的问题并改变它们的位置。

当我根据位置对事物进行硬编码时,没有像下面的代码示例那样重复。

@Override 
public int getItemViewType (int position) 
{ 
    switch (position) 
    {  
    case 0:
        return TYPE_HEADER; 

    case 8:
        return TYPE_HEADER;

    default:
        return TYPE_ITEMS; 
     }
}

但是当我像下面的代码一样更改它并使其成为动态而不是静态位置时,重复的开始。

String tempDate = "";
List<String> items = new ArrayList<>();
items.add("2017-01-01");
items.add("2017-01-01");
items.add("2017-01-02");
items.add("2017-01-02");
items.add("2017-01-02");
items.add("2017-01-03");
items.add("2017-01-03");
items.add("2017-01-03");
items.add("2017-01-04");
@Override 
public int getItemViewType (int position) 
{ 
   if(!tempDate.equalsIgnoreCase(items.get(position)){
       tempDate = items.get(position);
       return  TYPE_HEADER;
}  else{
       tempDate = items.get(position);
       return TYPE_ITEMS;       
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {

    switch (viewHolder.getItemViewType()) {
        case TYPE_HEADER:
            //Make your header view visible
            initialize the view resources of HeaderLayout xml 
            break;        

        case TYPE_ITEM:
            //Make your second header view visible
            initialize the view resources of ItemLayout xml
            break;
    }

}

据我所知,onBindViewHolder()、onCreateViewHolder() 的其他方法都很好。任何帮助表示赞赏。

【问题讨论】:

  • 我不确定这是否相关,但您的 getItemViewType() 有问题。 tempDate = items.get(position); 在 if 语句中并且未被使用。另外,您是否更新过列表或者它是静态的(或者在创建适配器后没有更新)?
  • 很难帮助,缺少重要的代码部分
  • @DoronYakovlev-Golani 是的,它是静态列表,我也在寻找 getItemViewType() 出现问题的原因。 tempDate = items.get(position);很好的说法。
  • @Manza 你还需要什么。告诉我。
  • @NareshSharma,您如何使用 tempDate?您对操作顺序的假设可能是错误的。

标签: android android-recyclerview


【解决方案1】:

我认为这里简单更好:

private List<String> items = new ArrayList<>();

@Override
public int getItemViewType (int position) {
    if (position == 0) {
        return TYPE_HEADER;
    }

    String textForPosition = items.get(position);
    String textForPrevPosition = items.get(position - 1);

    if (textForPosition.equalsIgnoreCase(textForPrevPosition)) {
        return TYPE_HEADER;
    }
    return TYPE_ITEM;
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {

    // Use dateText instead of tempDate
    String dateText = items.get(i);
    switch (viewHolder.getItemViewType()) {
        case TYPE_HEADER:
            //Make your header view visible initialize the view resources of HeaderLayout xml
            break;

        case TYPE_ITEM:
            //Make your second header view visible initialize the view resources of ItemLayout xml
            break;
    }

}

【讨论】:

    【解决方案2】:

    我认为问题出在那个代码部分:

    if(!tempDate.equalsIgnoreCase(items.get(position)){
       tempDate = items.get(position);
       return  TYPE_HEADER;
    }  
    else{
       tempDate = items.get(position);
       return TYPE_ITEMS;   
    }
    

    我建议在您的适配器中创建另一个名为 headers 的列表。 我已经实现了一个类,它扩展了我用于带有标题和项目的导航列表的 baseadapter。 也许您可以针对您的问题提出一些想法:

    /**
     * Adapter class for the navigation list. It handles items and section header items.
     */
    public class CDMNavListAdapter extends BaseAdapter {
    
      /**
       * Constructor
       *
       * @param p_Context the context
       */
      public CDMNavListAdapter(Context p_Context) {
        m_Inflater = (LayoutInflater) p_Context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      }
    
      /**
       * Adds an item to the list
       *
       * @param p_Item the item to add
       */
      public void addItem(CDMNavigationItem p_Item) {
        m_Data.add(p_Item);
        notifyDataSetChanged();
      }
    
      /**
       * Adds a section header item to the list
       *
       * @param p_Item the section head item
       */
      public void addSectionHeaderItem(String p_Item) {
        // CDMNavigationItem is just a wrapper: CDMNavigationItem(int p_iType , String p_Title, int p_iResIcon, String p_Count)
        m_Data.add(new CDMNavigationItem(ADMNavigationTypes.iSECTION_HEADER, p_Item, -1, "0"));
        m_SectionHeader.add(m_Data.size() - 1);
        notifyDataSetChanged();
      }
    
      @Override
      public int getItemViewType(int p_iPosition) {
        return m_SectionHeader.contains(p_iPosition) ? iTYPE_SEPARATOR : iTYPE_ITEM;
      }
    
      @Override
      public int getViewTypeCount() {
        return 2;
      }
    
      @Override
      public int getCount() {
        return m_Data.size();
      }
    
      @Override
      public CDMNavigationItem getItem(int p_iPosition) {
        return m_Data.get(p_iPosition);
      }
    
      @Override
      public long getItemId(int p_iPosition) {
        return p_iPosition;
      }
    
      @Override
      public View getView(int p_iPosition, View p_ConvertView, ViewGroup p_Parent) {
        int l_iRowType = getItemViewType(p_iPosition);
    
        // sets the text to the item / section head item
        CDMNavigationItem l_NavItem = m_Data.get(p_iPosition);
        switch(l_iRowType) {
          // item
          case iTYPE_ITEM:
            // item layout code
            break;
          // section header
          case iTYPE_SEPARATOR:
            // section header layout code
            break;
        }
    
        return p_ConvertView;
      }
    
      /**
       * Returns true if the item on the position is a section header item
       *
       * @param p_iPosition the position
       * @return true if the item on the position is a section header item
       */
      public boolean isSectionHeader(int p_iPosition) {
        return getItemViewType(p_iPosition) == iTYPE_SEPARATOR;
      }
    
      /**
       * Gets the position without header sections
       * @param p_iPosition the position
       * @return int the position without header sections
       */
      public int getPositionWithoutHeaderSections(int p_iPosition) {
        int l_iPositionWithoutHeaderSections = -1;
    
        for(int i = 0; i <= p_iPosition; i++) {
          if(!isSectionHeader(i))
            l_iPositionWithoutHeaderSections++;
        }
    
        return l_iPositionWithoutHeaderSections;
      }
    
      /**
       * Clears the data
       */
      public void clear() {
        m_Data.clear();
        m_SectionHeader.clear();
    
        notifyDataSetChanged();
      }
    
      private static final int iTYPE_ITEM = 0;
      private static final int iTYPE_SEPARATOR = 1;
    
      private List<CDMNavigationItem> m_Data = new ArrayList<>();
      private Set<Integer> m_SectionHeader = new TreeSet<>();
    
      private LayoutInflater m_Inflater;
    } 
    

    【讨论】:

      【解决方案3】:

      您可以使用此代码

      @Override
      public int getItemViewType(int position) {
          String tem = "";
          for (int i = 0; i < items.size(); i++) {
              if (!tem.equals(items.get(i))) {
                  tem=items.get(i);
                  if (i == position) {
                       return TYPE_HEADER;
                  }
              } else {
                  if (i == position) {
                      return TYPE_items;
                  }
              }
          }
          return -1;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-03
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        • 2020-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多