滚动上的recycleview在最后一个项目位置抛出java.lang.indexoutofboundsexception

x33g5p2x  于 2021-07-08  发布在  Java
关注(0)|答案(3)|浏览(313)

我有一个数组列表,其中包含15个项目,我在我的应用程序中使用admob原生广告在recycleview中,我有两个问题,我不太明白如何处理。第一个问题是我想在第7项之后显示第一个广告,但是第一个广告显示在第0个位置。第二个问题是当我到达列表的末尾时 java.lang.IndexOutOfBoundsException: . 这里有谁能帮我弄清楚我做错了什么吗?如果有人能帮我,我将不胜感激。这是我的密码:

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_AD= 0;
private static final int TYPE_NORMAL= 1;
public static final int ITEMS_PER_AD = 7;
Context context;
List<UnifiedNativeAd> mNativeAds = new ArrayList<>();
List<Quote> mQuotes;

private static final int NUMBER_OF_ADS = 5;
private AdLoader adLoader;
private String ADMOB_NATIVE_AD_UNIIT = "ca-app-pub-3940256099942544/2247696110";

public RecyclerViewAdapter(Context context, List<Quote> quotes) {
    this.context = context;
    this.mQuotes = quotes;
    notifyDataSetChanged();
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
    if(viewType == TYPE_AD)
    {
        View view = LayoutInflater.from(this.context).inflate(R.layout.ad_unified,parent,false);
        return new UnifiedNativeAdViewHolder(view);
    }
    View view = LayoutInflater.from(this.context).inflate(R.layout.quotes_list_item,parent,false);
    return new QuoteViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position)
{
    int viewType = getItemViewType(position);

    switch (viewType) {
        case TYPE_NORMAL :
            QuoteViewHolder vh = (QuoteViewHolder) holder;

            Quote current = (Quote) mQuotes.get(position);
            vh.txtName.setText(current.getQuote());
            vh.txtEmail.setText(current.getCategoryId());
            break;
        case TYPE_AD:
            //fall through
        default:
            UnifiedNativeAdViewHolder adViewHolder = (UnifiedNativeAdViewHolder) holder;
            AdLoader.Builder builder = new AdLoader.Builder(context, ADMOB_NATIVE_AD_UNIIT);
            adLoader = builder.forUnifiedNativeAd(unifiedNativeAd -> {
                mNativeAds.add(unifiedNativeAd);
                if (!adLoader.isLoading()) {
                    UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(position);
                    populateNativeAdView( nativeAd, (adViewHolder.getAdView()));
                    notifyDataSetChanged();
                }
            }).withAdListener(new AdListener(){
                @Override
                public void onAdFailedToLoad(LoadAdError loadAdError) {
                    super.onAdFailedToLoad(loadAdError);
                }
            })
                    .build();
            adLoader.loadAd(new AdRequest.Builder().build());
    }

}

@Override
public int getItemCount() {
    if (mNativeAds != null) return mQuotes.size() + mNativeAds.size();
    else return mQuotes.size();
}

@Override
public int getItemViewType(int position)
{
    return (position % ITEMS_PER_AD == 0) ? TYPE_AD: TYPE_NORMAL;
}

这是我的日志

2020-11-22 19:50:51.372 589-589/com.example.test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test, PID: 589
java.lang.IndexOutOfBoundsException: Index: 14, Size: 3
    at java.util.ArrayList.get(ArrayList.java:437)
    at com.example.test.RecyclerViewAdapter.lambda$onBindViewHolder$0$RecyclerViewAdapter(RecyclerViewAdapter.java:79)
    at com.example.test.-$$Lambda$RecyclerViewAdapter$rjtX5KhLYVLI7Av-VFSBy8gWizI.onUnifiedNativeAdLoaded(Unknown Source:6)
    at com.google.android.gms.internal.ads.zzagx.zza(com.google.android.gms:play-services-ads-lite@@19.5.0:6)
    at com.google.android.gms.internal.ads.zzagb.zza(com.google.android.gms:play-services-ads-lite@@19.5.0:18)
    at com.google.android.gms.internal.ads.zzgw.onTransact(com.google.android.gms:play-services-ads-base@@19.5.0:13)
    at android.os.Binder.transact(Binder.java:630)
    at ge.b(:com.google.android.gms.policy_ads_fdr_dynamite@204102000@204102000000.334548305.334548305:2)
    at com.google.android.gms.ads.internal.formats.client.au.a(:com.google.android.gms.policy_ads_fdr_dynamite@204102000@204102000000.334548305.334548305:0)
    at com.google.android.gms.ads.nonagon.ad.nativead.ad.run(Unknown Source:0)
    at android.os.Handler.handleCallback(Handler.java:794)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at qj.a(:com.google.android.gms.policy_ads_fdr_dynamite@204102000@204102000000.334548305.334548305:0)
    at com.google.android.gms.ads.internal.util.f.a(:com.google.android.gms.policy_ads_fdr_dynamite@204102000@204102000000.334548305.334548305:1)
    at qj.dispatchMessage(:com.google.android.gms.policy_ads_fdr_dynamite@204102000@204102000000.334548305.334548305:0)
    at android.os.Looper.loop(Looper.java:176)
    at android.app.ActivityThread.main(ActivityThread.java:6651)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)

这就是我犯错误的地方

UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(position);
dfddblmv

dfddblmv1#

这个问题是因为mnativeads的大小小于两个列表之和的大小,当你向上滚动时你调用索引如15,当然在mnativeads上找不到大小为7的列表。
不要使用mnativeads list的旧位置:

UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(position);

使用基于总和的新位置

UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(newPosition);
tjvv9vkg

tjvv9vkg2#

在getitemcount中,返回mquotes和mnativeads的大小之和,它大于mnativeads的大小。所以mnativeads在更高的位置抛出了一些异常。
您应该为这两个(mquotes和mnativeeads)使用一个列表,并相应地调整您的逻辑。
'''

@Override
    public int getItemCount() {

//Reason of your problem.

        if (mNativeAds != null) return mQuotes.size() + mNativeAds.size();
        else return mQuotes.size();
    }

'''

cyej8jka

cyej8jka3#

尝试以下3个代码更改: Quote current = (Quote) mQuotes.get(position); 更改为
Quote current = (Quote) mQuotes.get(position - position / ITEMS_PER_AD); UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(position); 更改为
UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get((position / ITEMS_PER_AD - 1) / mNativeAds.size()); return (position % ITEMS_PER_AD == 0) ? TYPE_AD: TYPE_NORMAL; 更改为 return (position != 0 && (position % ITEMS_PER_AD == 0)) ? TYPE_AD : TYPE_NORMAL;

相关问题