#java #android #android-recyclerview #admob
#java #Android #android-recyclerview #admob
Вопрос:
У меня есть список массивов, в котором содержится 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;
}
и вот мой logcat
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);
Ответ №1:
Эта проблема связана с тем, что размер mNativeAds меньше размера суммирования двух списков, при прокрутке вверх вы вызываете индекс, такой как 15, который, конечно, не найден в списке mNativeAds размером 7.
Вместо того, чтобы использовать старую позицию списка mNativeAds :
UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(position);
используйте новую позицию на основе суммирования
UnifiedNativeAd nativeAd = (UnifiedNativeAd) mNativeAds.get(newPosition);
Ответ №2:
в getItemCount вы возвращаете сумму размеров кавычек и mNativeAds, которая больше размера mNativeAds. Таким образом, mNativeAds выдает некоторое исключение в более высокой позиции.
Вы должны использовать один список для обоих (mQuotes и mNativeAds) и соответствующим образом адаптировать свою логику.
»’
@Override
public int getItemCount() {
//Reason of your problem.
if (mNativeAds != null) return mQuotes.size() mNativeAds.size();
else return mQuotes.size();
}
»’
Ответ №3:
Попробуйте следующие 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 amp;amp; (position % ITEMS_PER_AD == 0)) ? TYPE_AD : TYPE_NORMAL;