具有多种视图类型的RecyclerView适配器上的IndexOutOfBoundsException

时间:2016-05-13 23:06:47

标签: java android android-recyclerview

我有一个列表,我正在为每个下一个5元素的不同视图充气,该视图是广告的横幅。但现在我在方法getItemViewType()中收到错误。这就是我的代码的样子:

@Override
public int getItemViewType(int position) {
    if (jokes.get(position) != null) {
        // Here i should catch every 5 element in jokes array and change view
        if (position % 5 == 0 && position != 0) {
            return VIEW_TYPE_BANNER;
        }
        return VIEW_TYPE_ITEM;
    } else {
        return VIEW_TYPE_LOADING;
    }
}

这是方法getItemCount()

@Override
public int getItemCount() {
    return jokes == null ? 0 : jokes.size() + jokes.size() / 5;
}

注意:我从API中获取了18个项目。

编辑:

列表底部缺少一个项目。

enter image description here

2 个答案:

答案 0 :(得分:1)

您要做的是实施无休止的Recyclerview。

您的recyclerview适配器中的

就像这样写

 public class DataAdapter extends RecyclerView.Adapter {
 private final int VIEW_TYPE_ITEM = 1;
 private final int VIEW_TYPE_LOADING = 0;
 private final int VIEW_TYPE_BANNER = 2;

 ......
 ......

 @Override
 public int getItemViewType(int position) {
 if (jokes.get(position) != null) {
    if (position % 5 == 0 && position != 0) {
        return VIEW_TYPE_BANNER;
    }
    return VIEW_TYPE_ITEM;
} else {
    return VIEW_TYPE_LOADING;
   }
  }
}


 @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
 RecyclerView.ViewHolder vh;
 if (viewType == VIEW_TYPE_ITEM) {
 View v = LayoutInflater.from(parent.getContext()).inflate(
 R.layout.list_row, parent, false);
 vh = new StudentViewHolder(v);
 } 
 if(viewType == VIEW_TYPE_LOADING){
 View v = LayoutInflater.from(parent.getContext()).inflate(
 R.layout.progress_item, parent, false);
 vh = new ProgressViewHolder(v);
 }
 if(viewType == VIEW_TYPE_BANNER){
 //load your banner layout
 }
 return vh;
 }

 @Override
 public int getItemCount() {
 return studentList.size();
 }

并维护您是否应启用项目或横幅或从主活动文件加载的逻辑

答案 1 :(得分:1)

我认为你应该按照以下方式做点什么:

@Override
public int getItemViewType(int position) {
    if (position % 5 == 0 && position != 0) {
        return VIEW_TYPE_BANNER;
    } else if (position == getItemCount() - 1) {
        // Last item. Return the loading view.
        return VIEW_TYPE_LOADING;
    } else {
        return VIEW_TYPE_ITEM;
    }
}

@Override
public int getItemCount() {
    return jokes == null ? 0 
        : jokes.size() + jokes.size() / 5 + 1;
}

请记住,当您将VIEW_TYPE_ITEM与某个位置绑定时,您无法调用jokes.get(position)。您需要考虑之前插入的横幅视图。所以jokes.get(position - numberOfBannersBeforePosition)