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

Java 具有多个视图类型的RecyclerView适配器上的IndexOutOfBoundsException,java,android,android-recyclerview,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

我有一个列表,其中我为接下来的每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()

注意:我正在从API获取18项

编辑:

列表底部缺少一项


您要做的是实现无休止的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();
 }

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

我认为您应该按照以下思路进行操作:

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

请记住,当您将
视图\类型\项
与位置绑定时,您不能调用
笑话。获取(位置)
。您需要考虑之前插入的横幅视图。因此
笑话。get(position-numberOfBannersBeforePosition)

如果大小为18,则有效索引为0-17(包括)<代码>位置
笑话.size()+笑话.size()/5
肯定会给您带来比现在多20%的笑话。您从哪里调用getItemViewType()方法?请添加调用调用
getItemCount()
没有意义,而且完全不相关。@ElliottFrisch是的,这解决了我遇到的错误,但是现在视图类型加载被调用,进度条加载在底部不定式。@ElliottFrisch你知道如何解决这个新问题吗?进度条一直加载在列表底部?是的,但我还有一个视图。对于列表中的每5个下一个元素,我有一个横幅显示广告。没有
笑话。size()/5+1
我没有收到任何错误,但进度条一直在底部加载..@Dusan所以?这就是进度条的作用。关于物品数量,我认为我的建议应该是正确的。如果
crooks.size()
为18,则您希望有18个
+
3个横幅(在5、10、15处),即
Math.floor(18/5)
,最后是
+
1项。我就是这样理解你的问题的。我知道应该是这样,但为什么它总是在加载。我已经实现了EndlessRecyclerView,它应该会加载新页面。它加载第二页,但不加载最后一项。让我给你看看。
@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;
}