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>
    
  • Then create another layout file for adapter adapter_row_with_ads.xml with these changes.
  • <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的完整问题

    下一篇: 由于Admob广告,Recyclerview滞后滚动