我有一个数组列表,其中包含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);
3条答案
按热度按时间dfddblmv1#
这个问题是因为mnativeads的大小小于两个列表之和的大小,当你向上滚动时你调用索引如15,当然在mnativeads上找不到大小为7的列表。
不要使用mnativeads list的旧位置:
使用基于总和的新位置
tjvv9vkg2#
在getitemcount中,返回mquotes和mnativeads的大小之和,它大于mnativeads的大小。所以mnativeads在更高的位置抛出了一些异常。
您应该为这两个(mquotes和mnativeeads)使用一个列表,并相应地调整您的逻辑。
'''
'''
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;