RecyclerAdapter中的IndexOutOfBoundsException具有两种视图类型

时间:2016-07-05 09:53:52

标签: java android arraylist android-recyclerview indexoutofboundsexception

您会注意到,在feedItems.adAll(adItems)下面的行public class FeedRecyclerAdapter extends LoadingRowRecyclerAdapter { private static final int VIEW_TYPE_FEED = 1; private static final int VIEW_TYPE_AD = 2; private final Context context; private final List<Feed> feedItems; private final ImageLoader feedItemImageLoader; private FeedItemClickListener feedItemClickListener; private boolean isLongPressed = false; public FeedRecyclerAdapter(Context context, List<Feed> feedItems, ImageLoader feedItemImageLoader, List<Feed> adItems) { this.context = context; this.feedItems = feedItems; this.feedItemImageLoader = feedItemImageLoader; feedItems.addAll(adItems); // if (adItems.isEmpty()) { // Log.d(getClass().toString(), "IndexOutOfBoundsException!"); // } } // Differentiate between feedItem views and nativeAds @Override public int getItemViewType(int position) { int viewType = 1; if ((position % 9 == 0) && position != 1) viewType = 2; return viewType; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_FEED: return new FeedViewHolder(new FeedItemView(context)); case VIEW_TYPE_AD: return new AdViewHolder(new AdItemView(context)); } return super.onCreateViewHolder(parent, viewType); } @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if (getItemViewType(position) == VIEW_TYPE_FEED) { bindFeedItemView((FeedViewHolder) viewHolder, position); } else { bindAdItemView((AdViewHolder) viewHolder); } } @Override protected int getContentDataSize() { return feedItems.size(); } @Override protected int getViewType(int position) { if (position == 1) { return VIEW_TYPE_FEED; } else { return VIEW_TYPE_AD; } } class FeedViewHolder extends RecyclerView.ViewHolder { FeedItemView feedItemView; public FeedViewHolder(FeedItemView view) { super(view); this.feedItemView = view; } } class AdViewHolder extends RecyclerView.ViewHolder { AdItemView adItemView; public AdViewHolder(AdItemView view) { super(view); this.adItemView = view; } } private NativeAd nativeAd; private AdChoicesView adChoicesView; private void showNativeAd(AdViewHolder viewHolder){ AdSettings.addTestDevice("STRING"); nativeAd = new NativeAd(context, "STRING"); nativeAd.setAdListener(new AdListener() { @Override public void onError(Ad ad, AdError adError) { } @Override public void onAdLoaded(Ad ad) { final AdItemView adItemView = viewHolder.adItemView; // Setting the Text adItemView.nativeAdSocialContext.setText(nativeAd.getAdSocialContext()); adItemView.nativeAdCallToAction.setText(nativeAd.getAdCallToAction()); adItemView.nativeAdTitle.setText(nativeAd.getAdTitle()); adItemView.nativeAdBody.setText(nativeAd.getAdBody()); // Downloading and setting the ad icon NativeAd.Image adIcon = nativeAd.getAdIcon(); NativeAd.downloadAndDisplayImage(adIcon, adItemView.nativeAdIcon); // Download and setting the cover image /*NativeAd.Image adCoverImage = nativeAd.getAdCoverImage();*/ adItemView.nativeAdMedia.setNativeAd(nativeAd); // Add adChoices icon if (adChoicesView == null) { adChoicesView = new AdChoicesView(context, nativeAd, true); adItemView.addView(adChoicesView, 0); } nativeAd.registerViewForInteraction(adItemView); } @Override public void onAdClicked(Ad ad) { } }); nativeAd.loadAd(); } // For Ad Objects private void bindAdItemView(AdViewHolder viewHolder) { showNativeAd(viewHolder); } // For Feed Objects private void bindFeedItemView(FeedViewHolder viewHolder, int position) { final FeedItemView feedItemView = viewHolder.feedItemView; final Feed feedDesign = feedItems.get(position); // TODO we can probably conditionally show or hide these based on the type of feed item, same as in FeedActivitySingle feedItemView.showOrHideEditButton(true); feedItemView.showOrHideBuyButton(false); feedItemView.showOrHideFlipButton(false); feedItemView.showOrHidePriceText(false); // Set the results into TextViews feedItemView.setProductPriceText(String.valueOf(feedDesign.getDesign().getPrice())); feedItemView.setDownloadsText(String.valueOf(feedDesign.getDesign().getDownloadCount())); feedItemView.setLikesText(String.valueOf(feedDesign.getDesign().getLikesCount())); feedItemView.setUsernameText(feedDesign.getDesign().getAuthor().getUsername()); feedItemView.setTimestampText(feedDesign.getTimestampText()); feedItemView.getSaveImage().setImageResource(feedDesign.isInPersonalGallery() ? R.drawable.ic_action_saved : R.drawable.ic_not_saved); feedItemView.getLikeImage().setImageResource(feedDesign.isLiked() ? R.drawable.ic_action_like_feed_full : R.drawable.ic_action_like_feed); feedItemView.getTrashImage().setVisibility(ParseHelper.isCurrentUser(feedDesign.getDesign().getAuthor().getObjectId()) ? View.VISIBLE : View.GONE); feedItemView.getFeedSocialShareImage().setVisibility(View.VISIBLE); feedItemImageLoader.DisplayImage(feedDesign.getDesign().getCompressedImage().getUrl(), feedItemView.getImage(), feedItemView.getProgressBar()); if(feedDesign.getDesign().getAuthor().getProfilePicture() != null) { feedItemImageLoader.DisplayImage(feedDesign.getDesign().getAuthor().getProfilePicture().getUrl(), feedItemView.getProfilePicture(), null); // TODO should this use profilePictureFileCache? } else { viewHolder.feedItemView.getProfilePicture().setImageResource(R.drawable.ic_anonymous); } SetCommentViews(feedItemView, feedDesign.getComments()); SetClickListeners(feedItemView, feedDesign); } 下方,我已经注释了几行代码。每当发生此异常时,我都可以证明feedItems列表为空。

这是我的RecyclerAdapter:

07-05 11:51:30.179 22178-22178/com.elgami.customizer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.elgami.customizer, PID: 22178
java.lang.IndexOutOfBoundsException: Invalid index 5, size is 5
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.elgami.feed.FeedRecyclerAdapter.bindFeedItemView(FeedRecyclerAdapter.java:180)
at com.elgami.feed.FeedRecyclerAdapter.onBindViewHolder(FeedRecyclerAdapter.java:77)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5768)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5801)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5037)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1193)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1043)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4357)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:603)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

造成这种情况的原因是什么?每当您向下滚动Feed时,VM都会关闭并导致以下异常:

// Differentiate between feedItem views and nativeAds
@Override
public int getItemViewType(int position) {
    int viewType = 1;
    if ((position % 5 == 0) && position != 1) viewType = 2;
    return viewType;
}

修改

当商品的位置为5但不是10或15,或者我试过的任何其他数字时,例外情况就会停止:

 

我不明白为什么会这样。

1 个答案:

答案 0 :(得分:2)

  

java.lang.IndexOutOfBoundsException:索引5无效,大小为5

例如,你有一个包含5个项目的数组,你要求第6个项目,它会崩溃并抛出“IndexOutOfBoundsException”错误,因为数组小于你要求的数据。

- &GT; Understand Arraylist IndexOutOfBoundsException in Android