Recyclerview lag on scroll due to Admob ads
I want to load ads in RecyclerView ads are loaded successfully but it is casuing so much lag while scrolling
Following is code I have written in OnBindViewHolder method of Adapter
How to fix this lag?
((DealHolder) holder).adcardView.post(new Runnable() {
@Override
public void run() {
final NativeExpressAdView adView = new NativeExpressAdView(((DealHolder) holder).itemView.getContext());
final int adWidth = ((DealHolder) holder).adcardView.getWidth() - ((DealHolder) holder).adcardView.getPaddingLeft()
- ((DealHolder) holder).adcardView.getPaddingRight();
final int adHeight = ((DealHolder) holder).adcardView.getHeight() - ((DealHolder) holder).adcardView.getPaddingBottom()
- ((DealHolder) holder).adcardView.getPaddingTop();
final float scale = ((DealHolder) holder).adcardView.getResources().getDisplayMetrics().density;
AdSize adSize = new AdSize((int) (adWidth / scale), (int) (adHeight / scale));
adView.setAdSize(adSize);
adView.setAdUnitId(((DealHolder) holder).adcardView.getContext().getString(R.string.test_adunit_id));
AdRequest request = new AdRequest.Builder().addTestDevice("jjhjhbjhjhjhjhjhjhjh").build();
adView.loadAd(request);
adView.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
}
@Override
public void onAdFailedToLoad(int i) {
super.onAdFailedToLoad(i);
}
});
((DealHolder) holder).adcardView.removeAllViews();
((DealHolder) holder).adcardView.addView(adView);
}
});
Improvements :
Do not try to load your Adview when the user is trying to scroll. To do that make your adapter recylerView scroll aware and then check whether the scroll_state==RecylerView.Scroll_IDLE
, then only load your AdView.
If all your adViews have same width and height do not calculate it every time user scrolls, cache it in a variable.
Instead of dynamically adding and removing your NativeExpressAdView, use a XML version for it in your item_view. You can hide and show based on conditions. Set all the possible required attributes in XML view.
I think the problem is that you don't use main thread to display the ads.
I would recomment to do this in onViewAttachedWindow
. Because when the function triggered, layout manager had already its process such as mesuring and replace items etc.
In this way, you don't need to use another thread and main thread won't be blocked and the recyclerview will scroll smoothly.
Creating a new AdView for each view holder would be quite Resource hungry.
Instead of creating new adview on each view holder inflate adview after a certain interval like eg after every 5 or 10 items.
Create two different layouts to use in adapter one with ads and another without ads.
Override getItemViewType() method
public int getItemViewType(int position) { if (position % 10 == 0){ // Ad after every 10 items return 0; //use integer constant to identify view type is Adview. } return super.getItemViewType(position); }
in OnCreateViewHolder() method
@Override public ViewHolderClass onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == 0){ // Constant for Adview View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_row_with_ads, parent,false); return new ViewHolderClass(view, viewType); } View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_row, parent,false); return new ViewHolderClass(view); }
In your ViewholderClass create a second Constructor with parameters View and int
public class ViewHolderClass extends RecyclerView.ViewHolder{ ... public ViewHolderClass(View view){ ... } public ViewHolderClass(View view, int viewType){ ... // Initialize your adview here }
For your layouts. If your adapter_row.xml is like this :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" >
<android.support.v7.widget.CardView
android:id="@+id/base"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
// your main content
</android.support.v7.widget.CardView>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" >
<android.support.v7.widget.CardView
android:id="@+id/base"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
// your main content
</android.support.v7.widget.CardView>
<!--This is where you'll add your AdView-->
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/base"/>
</RelativeLayout>
This approach will reduce battery drainage and resource consumption and your app will be smoother
链接地址: http://www.djcxy.com/p/39966.html上一篇: 显示为NP的完整问题