具有多个布局的Recyclerview在滚动时重复项目

时间:2017-01-03 17:56:04

标签: android android-recyclerview

在具有多个布局的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()的其他方法都可以。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分: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;
    }

}

答案 1 :(得分:0)

我认为问题在于代码部分:

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;
} 

答案 2 :(得分:0)

您可以使用此代码

@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;
}