Android 在将 admob 原生广告添加到回收站视图后获得正确的项目位置
Android get correct item position after admob native ads are added to recycler view
我在 recycleview 中展示了 admob 原生广告,我这样做很成功,而且广告加载得很好。现在我面临的问题是我需要显示在另一个 activity 中点击的项目沿着它的位置但是当在 recycleview 中加载广告后点击任何项目时我得到了错误的位置。任何人都可以告诉我如何做到这一点,或者有更好的方法来完成我在这里想要实现的目标。这是我的代码
适配器
private final List<Object> modelBase;
Context context;
List<Quote> quoteList;
public AdapterList(Context context, List<Object> modelBase) {
this.context = context;
this.modelBase = modelBase;
}
public void setQuoteListForNextActivity(List<Quote> quoteList) {
this.quoteList = quoteList;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case 1:
UnifiedNativeAd nativeAd = (UnifiedNativeAd) modelBase.get(position);
populateNativeAdView(nativeAd, ((UnifiedNativeAdViewHolder) holder).getAdView());
break;
case 0:
//Not really needed code here as we have the default.
default:
MyListHolder menuItemHolder = (MyListHolder) holder;
Quote menuItem = (Quote) modelBase.get(position);
menuItemHolder.itemTitle.setText(menuItem.getQuote());
menuItemHolder.itemDescription.setText(String.valueOf(menuItem.getId()));
menuItemHolder.itemView.setOnClickListener(v -> {
Intent intent = new Intent(context, NextACtivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("mylist", (ArrayList<? extends Parcelable>) quoteList);
bundle.putInt("position",position);
intent.putExtras(bundle);
context.startActivity(intent);
});
}
}
@Override
public int getItemCount() {
return modelBase.size();
}
@Override
public int getItemViewType(int position) {
Object recyclerViewItem = modelBase.get(position);
if (recyclerViewItem instanceof UnifiedNativeAd) {
return 1;
}
return 0;
}
public class MyListHolder extends RecyclerView.ViewHolder {
private TextView itemTitle, itemDescription;
MyListHolder(View view) {
super(view);
itemTitle = view.findViewById(R.id.itemTitle);
itemDescription = view.findViewById(R.id.itemDescription);
}
}
//ViewHolder for Native Ad Data
class UnifiedNativeAdViewHolder extends RecyclerView.ViewHolder {
private UnifiedNativeAdView adView;
public UnifiedNativeAdView getAdView() {
return adView;
}
UnifiedNativeAdViewHolder(View view) {
super(view);
adView = view.findViewById(R.id.ad_view);
adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));
adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
adView.setBodyView(adView.findViewById(R.id.ad_body));
adView.setCallToActionView(adView.findViewById(R.id.ad_bt_visit));
adView.setIconView(adView.findViewById(R.id.ad_icon));
adView.setPriceView(adView.findViewById(R.id.ad_price));
adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
adView.setStoreView(adView.findViewById(R.id.ad_store));
adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));
}
}
这是我的 MainActivity
private String ADMOB_NATIVE_AD_UNIIT = "ca-app-pub-3940256099942544/2247696110";
AdLoader adLoader;
// The total number of native ads to load.
private static final int NUMBER_OF_ADS = 5;
//FIRST AD POSITION (Index number, means List position + 1)
public static final int FIRST_AD_START_POSITION = 7;
AdapterList adapterList;
List<Object> mDataList = new ArrayList<>();
List<UnifiedNativeAd> mNativeAds = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MobileAds.initialize(this, initializationStatus -> {
});
AppDatabase database = AppDatabase.getDatabase(this);
QuoteDao dao = database.quoteDao();
RecyclerView recyclerView = findViewById(R.id.quote_recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
mDataList.addAll( dao.getAllQuotes());
adapterList = new AdapterList(this,mDataList);
recyclerView.setAdapter(adapterList);
adapterList.setQuoteListForNextActivity(dao.getAllQuotes());
loadNativeAds();
}
private void insertAdsInMenuItems() {
if (mNativeAds.size() <= 0) {
return;
}
int offset = (mDataList.size() / mNativeAds.size()) + 1;
int index = FIRST_AD_START_POSITION;
for (UnifiedNativeAd ad : mNativeAds) {
mDataList.add(index, ad);
index = index + offset;
}
adapterList.notifyDataSetChanged();
}
private void loadNativeAds() {
AdLoader.Builder builder = new AdLoader.Builder(this, ADMOB_NATIVE_AD_UNIIT);
adLoader = builder.forUnifiedNativeAd(
unifiedNativeAd -> {
mNativeAds.add(unifiedNativeAd);
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}).withAdListener(
new AdListener() {
@Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}
}).build();
adLoader.loadAds(new AdRequest.Builder().build(), NUMBER_OF_ADS);
}
您可以尝试以下两种解决方案:
解决方案一:
计数 position 之前的数据项[ItemViewType 为 0]。
int originalListPosition = 0;
for (int i = 0; i < position; i++) {
if (getItemViewType(i) == 0) originalListPosition++;
}
方案二:
将 index 和 offset 从 Activity 传递给 Adapter 并进行计算。
int originalListPosition;
if (position < index) originalListPosition = position;
else {
originalListPosition = position - ((position - index) / offset + 1);
}
我在 recycleview 中展示了 admob 原生广告,我这样做很成功,而且广告加载得很好。现在我面临的问题是我需要显示在另一个 activity 中点击的项目沿着它的位置但是当在 recycleview 中加载广告后点击任何项目时我得到了错误的位置。任何人都可以告诉我如何做到这一点,或者有更好的方法来完成我在这里想要实现的目标。这是我的代码
适配器
private final List<Object> modelBase;
Context context;
List<Quote> quoteList;
public AdapterList(Context context, List<Object> modelBase) {
this.context = context;
this.modelBase = modelBase;
}
public void setQuoteListForNextActivity(List<Quote> quoteList) {
this.quoteList = quoteList;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case 1:
UnifiedNativeAd nativeAd = (UnifiedNativeAd) modelBase.get(position);
populateNativeAdView(nativeAd, ((UnifiedNativeAdViewHolder) holder).getAdView());
break;
case 0:
//Not really needed code here as we have the default.
default:
MyListHolder menuItemHolder = (MyListHolder) holder;
Quote menuItem = (Quote) modelBase.get(position);
menuItemHolder.itemTitle.setText(menuItem.getQuote());
menuItemHolder.itemDescription.setText(String.valueOf(menuItem.getId()));
menuItemHolder.itemView.setOnClickListener(v -> {
Intent intent = new Intent(context, NextACtivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("mylist", (ArrayList<? extends Parcelable>) quoteList);
bundle.putInt("position",position);
intent.putExtras(bundle);
context.startActivity(intent);
});
}
}
@Override
public int getItemCount() {
return modelBase.size();
}
@Override
public int getItemViewType(int position) {
Object recyclerViewItem = modelBase.get(position);
if (recyclerViewItem instanceof UnifiedNativeAd) {
return 1;
}
return 0;
}
public class MyListHolder extends RecyclerView.ViewHolder {
private TextView itemTitle, itemDescription;
MyListHolder(View view) {
super(view);
itemTitle = view.findViewById(R.id.itemTitle);
itemDescription = view.findViewById(R.id.itemDescription);
}
}
//ViewHolder for Native Ad Data
class UnifiedNativeAdViewHolder extends RecyclerView.ViewHolder {
private UnifiedNativeAdView adView;
public UnifiedNativeAdView getAdView() {
return adView;
}
UnifiedNativeAdViewHolder(View view) {
super(view);
adView = view.findViewById(R.id.ad_view);
adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));
adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
adView.setBodyView(adView.findViewById(R.id.ad_body));
adView.setCallToActionView(adView.findViewById(R.id.ad_bt_visit));
adView.setIconView(adView.findViewById(R.id.ad_icon));
adView.setPriceView(adView.findViewById(R.id.ad_price));
adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
adView.setStoreView(adView.findViewById(R.id.ad_store));
adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));
}
}
这是我的 MainActivity
private String ADMOB_NATIVE_AD_UNIIT = "ca-app-pub-3940256099942544/2247696110";
AdLoader adLoader;
// The total number of native ads to load.
private static final int NUMBER_OF_ADS = 5;
//FIRST AD POSITION (Index number, means List position + 1)
public static final int FIRST_AD_START_POSITION = 7;
AdapterList adapterList;
List<Object> mDataList = new ArrayList<>();
List<UnifiedNativeAd> mNativeAds = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MobileAds.initialize(this, initializationStatus -> {
});
AppDatabase database = AppDatabase.getDatabase(this);
QuoteDao dao = database.quoteDao();
RecyclerView recyclerView = findViewById(R.id.quote_recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
mDataList.addAll( dao.getAllQuotes());
adapterList = new AdapterList(this,mDataList);
recyclerView.setAdapter(adapterList);
adapterList.setQuoteListForNextActivity(dao.getAllQuotes());
loadNativeAds();
}
private void insertAdsInMenuItems() {
if (mNativeAds.size() <= 0) {
return;
}
int offset = (mDataList.size() / mNativeAds.size()) + 1;
int index = FIRST_AD_START_POSITION;
for (UnifiedNativeAd ad : mNativeAds) {
mDataList.add(index, ad);
index = index + offset;
}
adapterList.notifyDataSetChanged();
}
private void loadNativeAds() {
AdLoader.Builder builder = new AdLoader.Builder(this, ADMOB_NATIVE_AD_UNIIT);
adLoader = builder.forUnifiedNativeAd(
unifiedNativeAd -> {
mNativeAds.add(unifiedNativeAd);
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}).withAdListener(
new AdListener() {
@Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
if (!adLoader.isLoading()) {
insertAdsInMenuItems();
}
}
}).build();
adLoader.loadAds(new AdRequest.Builder().build(), NUMBER_OF_ADS);
}
您可以尝试以下两种解决方案:
解决方案一: 计数 position 之前的数据项[ItemViewType 为 0]。
int originalListPosition = 0;
for (int i = 0; i < position; i++) {
if (getItemViewType(i) == 0) originalListPosition++;
}
方案二: 将 index 和 offset 从 Activity 传递给 Adapter 并进行计算。
int originalListPosition;
if (position < index) originalListPosition = position;
else {
originalListPosition = position - ((position - index) / offset + 1);
}