Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Native express ads in Listview with CursorAdapter

I have listview with cursoradapter. Now i want to implement native express ads in listview.

I have seen the implementation of Native ads with simple baseAdapter,in that generally we are using List<Object> for passing data to adapter and check type of item inside getView() method to add ads.

 @Override
public View getView(int position, View convertView, ViewGroup parent)
        throws IllegalArgumentException {
    Object item = getItem(position);

    if (item instanceof Listing) {
        // Listing items already have all the data required, so they just need to be displayed.
                  return listingLayout;
    } else if (item instanceof AdPlacement) {
        return ((AdPlacement) item).getView(convertView, parent);
    } else {
        // Any unknown items will cause exceptions, though this shouldn't ever happen.
        throw new IllegalArgumentException(
                String.format("Adapter can't handle getView() for list item of type %s",
                        item.getClass().getName()));
    }


}

How to check this condition in cursoradapter as cursoradapter only have method newItem() with cursor details

 @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = LayoutInflater.from(context).inflate(R.layout.list_item_station, parent, false);
        ViewHolder holder = new ViewHolder();

        v.setTag(holder);
        return v;
    }

How to add native ads after every 10 items in cursoradapter

Bellow is the current code i am using to add data in the list.

public class StationsCursorAdapter extends CursorAdapter{


    public StationsCursorAdapter(Context context) {
        super(context, null, true);
            }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = LayoutInflater.from(context).inflate(R.layout.list_item_station, parent, false);
        ViewHolder holder = new ViewHolder();

        v.setTag(holder);
        return v;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.titleTextView.setText(cursor.getString(cursor.getColumnIndex(Station.NAME)));
    }

    private static final class ViewHolder {
               TextView titleTextView;
           }

}
like image 985
Om Infowave Developers Avatar asked Jun 09 '17 12:06

Om Infowave Developers


3 Answers

create file list_item_native_ad.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="132dp">

    <com.google.android.gms.ads.NativeExpressAdView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/nativeAd"
        ads:adSize="FULL_WIDTHx132"
        ads:adUnitId="@string/native_ad_unit_id"/>
</LinearLayout>

Create NativeAdViewHelperinside your adapter.

public class NativeAdViewHolder extends RecyclerView.ViewHolder {

        private final NativeExpressAdView mNativeAd;

        public NativeAdViewHolder(View itemView) {
            super(itemView);
            mNativeAd = (NativeExpressAdView) itemView.findViewById(R.id.nativeAd);
            mNativeAd.setAdListener(new AdListener() {
                @Override
                public void onAdLoaded() {
                    super.onAdLoaded();
                    if (mItemClickListener != null) {
                        Log.i(TAG, "onAdLoaded");
                    }
                }

                @Override
                public void onAdClosed() {
                    super.onAdClosed();
                    if (mItemClickListener != null) {
                        Log.i(TAG, "onAdClosed");
                    }
                }

                @Override
                public void onAdFailedToLoad(int errorCode) {
                    super.onAdFailedToLoad(errorCode);
                    if (mItemClickListener != null) {
                        Log.i(TAG, "onAdFailedToLoad");
                    }
                }

                @Override
                public void onAdLeftApplication() {
                    super.onAdLeftApplication();
                    if (mItemClickListener != null) {
                        Log.i(TAG, "onAdLeftApplication");
                    }
                }

                @Override
                public void onAdOpened() {
                    super.onAdOpened();
                    if (mItemClickListener != null) {
                        Log.i(TAG, "onAdOpened");
                    }
                }
            });
            AdRequest adRequest = new AdRequest.Builder()
                    .addTestDevice(MainActivity.TEST_DEVICE_ID)
                    .build();
            //You can add the following code if you are testing in an emulator
            /*AdRequest adRequest = new AdRequest.Builder()
                .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                .build();*/
            mNativeAd.loadAd(adRequest);
        }
    }

Override method getItemViewType() inside your adapter

@Override
    public int getItemViewType(int position) {
        if (position>1 && position % 3 == 0) {//in your case replace % 3 with % 10.
            return NATIVE_AD_VIEW_TYPE;
        }
        return DEFAULT_VIEW_TYPE;
    }

Override method getViewTypeCount()

@Override
public int getViewTypeCount() {
            return 2;
        }

inside your newView() method

@Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view;
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        switch (viewType) {
            default:
                view = layoutInflater
                        .inflate(R.id.content, parent, false);
                return new ViewHolder(view);
            case NATIVE_AD_VIEW_TYPE:
                view = layoutInflater.inflate(R.layout.list_item_native_ad, parent, false);
                return new NativeAdViewHolder(view);
        }
    }

inside your bindView() method

@Override
    public void bindView(View view, Context context, Cursor cursor) {
        if (!(holder instanceof ViewHolder)) {
            return;
        }
        holder.titleTextView.setText(cursor.getString(cursor.getColumnIndex(Station.NAME)));
    }

Hope it will help you!

like image 67
N.Droid Avatar answered Oct 29 '22 17:10

N.Droid


I ll suggest you not to use cursor adapter for this case, as it will be inefficient, rather you should fetch data from Database to a list, and use CustomAdapter extending BaseAdapter to bind views accordingly.

And if you have to use cursor adapter only, then you need to modify your cursor data to have ads item at every 10th position. You could alter your cursor like :

    public Cursor getModifiedCursorWithAds(Cursor cursor) {
        int size = cursor.getCount();
        MatrixCursor matrixCursor = new MatrixCursor(cursor.getColumnNames());
        int totalAds = size / 10;
        int negativeIds = -1;
        cursor.moveToFirst();
        //assuming only two columns in cursor
        for (int i = 0; i < (size + totalAds); i++) {
            if (i % 10 == 0 && i != 0) {
                matrixCursor.addRow(new String[]{"" + negativeIds--, "Ads data"}); //add dummy data for displaying ads(on the basis of negative ids, ad will be displayed
            } else {
                matrixCursor.addRow(new String[]{cursor.getString(0), cursor.getString(1)}); //add data from actual cursor, if you have more than 2 data modify this statement
                cursor.moveToNext();
            }
        }
        cursor.close();
        return matrixCursor;
    }

Modify you newView to return different view for ads and other items and bind accordinly in bindView callback.

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view;
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        int viewType = cursor.getInt(0);
        if (viewType >= 0) {
            view = layoutInflater
                    .inflate(R.id.list_item_content, parent, false);
            ViewHolder holder = new ViewHolder();
            view.setTag(holder);
        } else {
            view = layoutInflater.inflate(R.layout.list_item_native_ad, parent, false);
            AdViewHolder holder = new AdViewHolder();

            view.setTag(holder);
        }
        return view;
    }

I have not tested above code, so it may need some changes to make it work.

like image 35
abhishesh Avatar answered Oct 29 '22 17:10

abhishesh


Implementation View Item type a little another. You should define different types of layout, and inflating. Take a look RecyclerView Item Type.

After you create correct View Inflating, you can check type in OnBind method, and implement another behavior for each View.

@Override
public void bindView(View view, Context context, Cursor cursor) {
    ViewHolder holder = (ViewHolder) view.getTag();
    if (holder instance of Dog) {
         // Handle one case
    } else {
         // Handle other case
    }
}
like image 1
GensaGames Avatar answered Oct 29 '22 16:10

GensaGames