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;
}
}
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 NativeAdViewHelper
inside 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!
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.
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With