I have a recyclerview and I want to put a banner ad after every 10 items in it. However, if I do as in the official document, that is, if I pre-load the ads, this time the ad display rate decreases (I get a very low display rate around 20-30%).
Another method is to load the onCreateViewHolder or the holder containing the ad in the constructor. However, this time it only loads 1 ad at a time.
Another method is to load it in onBindViewHolder as in my example. However, this is not the right option because onLoading occurs when the creative leaves the screen while scrolling and enters it again, that is, the bind operation is performed again. I think this would also be a policy violation.
In short, all these solutions do not work. I want a different and correct method. I don't want the recyclerview to load over and over again when it scrolls.
This method is very old and pre-loading ads is not really correct. because if the user doesn't scroll to the end of the list, he won't get any views. While the match rate is 80-90%, the display rate remains at 20%. This is not true. Please bring a solution
public class TestActivity extends AppCompatActivity {
RecyclerView recyclerView;
TestAdapter testAdapter;
List<String> itemList = new ArrayList<>();
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
for (int i = 0; i < 200; i++) {
itemList.add("Item " + i);
if (i % 10 == 0) {
itemList.add(null);
}
}
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
testAdapter = new TestAdapter(itemList);
recyclerView.setAdapter(testAdapter);
}
}
TestAdapter
public class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<String> itemList;
static final int CONTENT_TYPE = 0;
static final int AD_TYPE = 1;
public TestAdapter(List<String> itemList) {
this.itemList = itemList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == CONTENT_TYPE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_item, parent, false);
return new ViewHolder(view);
} else {
View adView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_ad, parent, false);
return new AdRecyclerHolder(adView);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ViewHolder viewHolder) {
viewHolder.idText.setText(String.valueOf(position));
viewHolder.title.setText(itemList.get(position));
} else if (holder instanceof AdRecyclerHolder adHolder) {
AdRequest adRequest = new AdRequest.Builder().build();
adHolder.mAdView.loadAd(adRequest);
adHolder.mAdView.setAdListener(new AdListener() {
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
Log.e("TAG_AD", "onAdFailedToLoad");
super.onAdFailedToLoad(loadAdError);
}
@Override
public void onAdLoaded() {
Log.e("TAG_AD", "onAdLoaded");
}
});
}
}
@Override
public int getItemCount() {
return itemList.size();
}
@Override
public int getItemViewType(int position) {
if (itemList.get(position) == null) {
return AD_TYPE;
} else {
return CONTENT_TYPE;
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView idText, title;
public ViewHolder(@NonNull View itemView) {
super(itemView);
idText = itemView.findViewById(R.id.id_text);
title = itemView.findViewById(R.id.title);
}
}
public static class AdRecyclerHolder extends RecyclerView.ViewHolder {
AdView mAdView;
public AdRecyclerHolder(@NonNull View itemView) {
super(itemView);
mAdView = itemView.findViewById(R.id.adView);
}
}
}