diff --git a/README.md b/README.md
index f4e560c..2a50b67 100644
--- a/README.md
+++ b/README.md
@@ -1,58 +1,15 @@
Admob Adapter
======================
+The reference to the [DOCUMENTATION](https://github.com/clockbyte/admobadapter/wiki/Cookbook) for people who are in hurry!
+
Admob Adapter is an Android library that makes it easy to integrate [Admob native ads](https://firebase.google.com/docs/admob/android/native) (both Express and Advanced) into ```ListView/RecyclerView``` in the way that is shown in the following image/animation.
![](https://raw.githubusercontent.com/clockbyte/admobadapter/master/screenshots/device-2015-08-28-012121.png)
![](https://raw.githubusercontent.com/clockbyte/admobadapter/master/screenshots/ezgif.com-gif-maker.gif "Demo gif")
-#Main features
-
-* Publish of the native ads without changing the logic of your ```Adapter```
-* Customization: you can easily set the maximum count of ads per list, the count of items shown between ad blocks and a custom layouts for ads blocks.
-* Easy to update ad blocks periodically
-
-The admobadapter-sampleapp shows the available features and customizations.
-
-# Installation
-
-##Cloning
-First of all you will have to clone the library.
-```shell
-git clone https://github.com/clockbyte/admobadapter.git
-```
-
-Now that you have the library you will have to import it into Android Studio.
-In Android Studio navigate the menus like this.
-```
-File -> Import Project ...
-```
-In the following dialog navigate to ```admobadapter-master``` which you cloned to your computer in the previous steps and select the `build.gradle`.
-
-##Or
-you also can simply copy all the *.java from
-```
-admobadapter/admobadapter/src/main/java/com/clockbyte/admobadapter/
-```
-to your ```java``` sources folder (feel free to edit the package names in all files but please leave the License header as is).
-
-and all the *.xml from
-```
-admobadapter/admobadapter/src/main/res/layout/
-```
-to your ```res/layout``` folder.
-Also please don't forget to copy the string resource ```test_admob_unit_id``` from ```admobadapter/admobadapter/src/main/res/values/strings.xml``` to your ```strings.xml``` file. Then kindly use it as demonstrated in the sampleapp demo.
-When you'll be ready to deploy your app to Release you'll have to register in the Admob and create Ad unit ID there. Then you'd kindly replace the ```test_admob_unit_id``` with your real Ad unit ID. And please don't forget to use the test ID instead of real one when you're debugging/testing your app otherwise Admob can ban your account (artificial inflating of impressions and so on).
-
-#Base usage
-The quick and dirty start is shown in the sampleapp of the project (to switch the sample between the RecyclerView and ListView examples kindly edit the ```AndroidManifest.xml```)
-
-The Developer's guide on native ads could be found [here](https://developers.google.com/admob/android/native).
-
-The cook recipes could be found in the [Wiki](https://github.com/clockbyte/admobadapter/wiki/Cookbook)
-
-Also feel free to ask me.
+You can read the rest info (main features, installation, base usage and so on) at the [project's home page](https://github.com/clockbyte/admobadapter/wiki/Home) if you wish.
#Contributions
Contributions are very welcome. If you find a bug in the library or want an improvement and feel you can work on it yourself, fork + pull request and i'll appreciate it much!
diff --git a/admobadapter/build.gradle b/admobadapter/build.gradle
index 8979ef8..2012f99 100644
--- a/admobadapter/build.gradle
+++ b/admobadapter/build.gradle
@@ -17,7 +17,7 @@ android {
buildToolsVersion "23.0.3"
defaultConfig {
- minSdkVersion 9
+ minSdkVersion 11
targetSdkVersion 22
versionCode 1
versionName "1.0"
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterCalculator.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterCalculator.java
new file mode 100644
index 0000000..b0cb4c1
--- /dev/null
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterCalculator.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2015 Yahoo Inc. All rights reserved.
+ * Copyright 2016 Clockbyte LLC. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.clockbyte.admobadapter;
+
+import android.util.Log;
+
+public class AdmobAdapterCalculator {
+
+ protected AdmobAdapterWrapperInterface mAdmobAdapter;
+
+ public AdmobAdapterCalculator(AdmobAdapterWrapperInterface admobAdapter){
+ mAdmobAdapter = admobAdapter;
+ }
+
+ protected int mNoOfDataBetweenAds;
+ /*
+ * Gets the number of your data items between ad blocks, by default it equals to 10.
+ * You should set it according to the Admob's policies and rules which says not to
+ * display more than one ad block at the visible part of the screen
+ * so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
+ */
+ public int getNoOfDataBetweenAds() {
+ return mNoOfDataBetweenAds;
+ }
+
+ /*
+ * Sets the number of your data items between ad blocks, by default it equals to 10.
+ * You should set it according to the Admob's policies and rules which says not to
+ * display more than one ad block at the visible part of the screen
+ * so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
+ */
+ public void setNoOfDataBetweenAds(int mNoOfDataBetweenAds) {
+ this.mNoOfDataBetweenAds = mNoOfDataBetweenAds;
+ }
+
+ protected int firstAdIndex = 0;
+
+ public int getFirstAdIndex() {
+ return firstAdIndex;
+ }
+
+ /*
+ * Sets the first ad block index (zero-based) in the adapter, by default it equals to 0
+ */
+ public void setFirstAdIndex(int firstAdIndex) {
+ this.firstAdIndex = firstAdIndex;
+ }
+
+ protected int mLimitOfAds;
+
+ /*
+ * Gets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
+ */
+ public int getLimitOfAds() {
+ return mLimitOfAds;
+ }
+
+ /*
+ * Sets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
+ */
+ public void setLimitOfAds(int mLimitOfAds) {
+ this.mLimitOfAds = mLimitOfAds;
+ }
+
+
+ public int getAdsCountToPublish(){
+ //int cntFetched = adFetcher.getFetchedAdsCount();
+ //if(cntFetched == 0) return 0;
+ int expected = 0;
+ if(mAdmobAdapter.getAdapterCount() > 0 && mAdmobAdapter.getAdapterCount()>= getOffsetValue()+1)
+ expected = (mAdmobAdapter.getAdapterCount() - getOffsetValue()) / getNoOfDataBetweenAds() + 1;
+ expected = Math.max(0, expected);
+ //int noOfAds = Math.min(cntFetched, expected);
+ return Math.min(expected, getLimitOfAds());
+ }
+
+ /**
+ * Translates an adapter position to an actual position within the underlying dataset.
+ *
+ * @param position the adapter position
+ * @return the original position that the adapter position would have been without ads
+ */
+ public int getOriginalContentPosition(int position) {
+ int noOfAds = getAdsCountToPublish();
+ // No of spaces for ads in the dataset, according to ad placement rules
+ int adSpacesCount = (getAdIndex(position) + 1);
+ int originalPosition = position - Math.min(adSpacesCount, noOfAds);
+ Log.d("POSITION", position + " is originally " + originalPosition);
+
+ return originalPosition;
+ }
+
+ /**
+ * Determines if an ad can be shown at the given position. Checks if the position is for
+ * an ad, using the preconfigured ad positioning rules; and if a native ad object is
+ * available to place in that position.
+ *
+ * @param position the adapter position
+ * @return true
if ads can
+ */
+ public boolean canShowAdAtPosition(int position) {
+
+ // Is this a valid position for an ad?
+ // Is an ad for this position available?
+ return isAdPosition(position) && isAdAvailable(position);
+ }
+
+ /**
+ * Gets the ad index for this adapter position within the list of currently fetched ads.
+ *
+ * @param position the adapter position
+ * @return the index of the ad within the list of fetched ads
+ */
+ public int getAdIndex(int position) {
+ int index = -1;
+ if(position >= getOffsetValue())
+ index = (position - getOffsetValue()) / (getNoOfDataBetweenAds()+1);
+ Log.d("POSITION", "index " + index + " for position " + position);
+ return index;
+ }
+
+ /**
+ * Checks if adapter position is an ad position.
+ *
+ * @param position the adapter position
+ * @return {@code true} if an ad position, {@code false} otherwise
+ */
+ public boolean isAdPosition(int position) {
+ int result = (position - getOffsetValue()) % (getNoOfDataBetweenAds() + 1);
+ return result == 0;
+ }
+
+ public int getOffsetValue() {
+ return getFirstAdIndex() > 0 ? getFirstAdIndex() : 0;
+ }
+
+ /**
+ * Checks if an ad is available for this position.
+ *
+ * @param position the adapter position
+ * @return {@code true} if an ad is available, {@code false} otherwise
+ */
+ public boolean isAdAvailable(int position) {
+ int adIndex = getAdIndex(position);
+ int firstAdPos = getOffsetValue();
+
+ return position >= firstAdPos && adIndex >= 0 && adIndex < getLimitOfAds();
+ }
+
+
+}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapper.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapper.java
index 5e0e347..26b2265 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapper.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapper.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.database.DataSetObserver;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +33,7 @@
* Adapter that has common functionality for any adapters that need to show ads in-between
* other data.
*/
-public class AdmobAdapterWrapper extends BaseAdapter implements AdmobFetcherBase.AdmobListener {
+public class AdmobAdapterWrapper extends BaseAdapter implements AdmobFetcherBase.AdmobListener, AdmobAdapterWrapperInterface {
private final String TAG = AdmobAdapterWrapper.class.getCanonicalName();
@@ -59,6 +60,17 @@ public void onInvalidated() {
AdmobFetcher adFetcher;
Context mContext;
+ private AdmobAdapterCalculator AdapterCalculator = new AdmobAdapterCalculator(this);
+ /*
+ * Gets an object which incapsulates transformation of the source and ad blocks indices
+ */
+ public AdmobAdapterCalculator getAdapterCalculator(){return AdapterCalculator;}
+ /*
+* Injects an object which incapsulates transformation of the source and ad blocks indices. You could override calculations
+* by inheritance of AdmobAdapterCalculator class
+*/
+ public void setAdapterCalculator(AdmobAdapterCalculator adapterCalculatordmob){AdapterCalculator = adapterCalculatordmob;}
+
private static final int VIEW_TYPE_COUNT = 2;
private static final int VIEW_TYPE_AD_CONTENT = 1;
@@ -67,8 +79,6 @@ public void onInvalidated() {
private final static int DEFAULT_NO_OF_DATA_BETWEEN_ADS = 10;
private final static int DEFAULT_LIMIT_OF_ADS = 3;
- private int mNoOfDataBetweenAds;
-
/*
* Gets the number of your data items between ad blocks, by default it equals to 10.
* You should set it according to the Admob's policies and rules which says not to
@@ -76,9 +86,8 @@ public void onInvalidated() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public int getNoOfDataBetweenAds() {
- return mNoOfDataBetweenAds;
+ return AdapterCalculator.getNoOfDataBetweenAds();
}
-
/*
* Sets the number of your data items between ad blocks, by default it equals to 10.
* You should set it according to the Admob's policies and rules which says not to
@@ -86,23 +95,31 @@ public int getNoOfDataBetweenAds() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public void setNoOfDataBetweenAds(int mNoOfDataBetweenAds) {
- this.mNoOfDataBetweenAds = mNoOfDataBetweenAds;
+ AdapterCalculator.setNoOfDataBetweenAds(mNoOfDataBetweenAds);
}
- private int mLimitOfAds;
+ public int getFirstAdIndex() {
+ return AdapterCalculator.getFirstAdIndex();
+ }
+ /*
+ * Sets the first ad block index (zero-based) in the adapter, by default it equals to 0
+ */
+ public void setFirstAdIndex(int firstAdIndex) {
+ AdapterCalculator.setFirstAdIndex(firstAdIndex);
+ }
/*
* Gets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public int getLimitOfAds() {
- return mLimitOfAds;
+ return AdapterCalculator.getLimitOfAds();
}
/*
* Sets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public void setLimitOfAds(int mLimitOfAds) {
- this.mLimitOfAds = mLimitOfAds;
+ AdapterCalculator.setLimitOfAds(mLimitOfAds);
}
private int mContentAdsLayoutId;
@@ -138,10 +155,18 @@ public void setInstallAdsLayoutId(int mInstallAdsLayoutId) {
}
/*
- *Sets a test device ID. Normally you don't have to set it
+ *Add a test device ID.
*/
+ public void addTestDeviceId(String testDeviceId) {
+ adFetcher.addTestDeviceId(testDeviceId);
+ }
+
+ /*
+*Sets a test device ID. Normally you don't have to set it
+*/
+ @Deprecated
public void setTestDeviceId(String testDeviceId) {
- adFetcher.setTestDeviceId(testDeviceId);
+ adFetcher.addTestDeviceId(testDeviceId);
}
/*
@@ -191,7 +216,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
}
return lvi2;
default:
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getView(origPos, convertView, parent);
}
}
@@ -238,19 +263,13 @@ public int getCount() {
No of currently fetched ads, as long as it isn't more than no of max ads that can
fit dataset.
*/
- int noOfAds = getAdsCountToPublish();
+ int noOfAds = AdapterCalculator.getAdsCountToPublish();
return mAdapter.getCount() > 0 ? mAdapter.getCount() + noOfAds : 0;
} else {
return 0;
}
}
- public int getAdsCountToPublish(){
- int noOfAds = Math.min(adFetcher.getFetchedAdsCount(),
- mAdapter.getCount() / getNoOfDataBetweenAds());
- return Math.min(noOfAds, getLimitOfAds());
- }
-
/**
* Gets the item in a given position in the dataset. If an ad is to be returned,
* a {@link NativeAd} object is returned.
@@ -261,11 +280,11 @@ public int getAdsCountToPublish(){
@Override
public Object getItem(int position) {
- if (canShowAdAtPosition(position)) {
- int adPos = getAdIndex(position);
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
+ int adPos = AdapterCalculator.getAdIndex(position);
return adFetcher.getAdForIndex(adPos);
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItem(origPos);
}
}
@@ -282,78 +301,16 @@ public int getViewTypeCount() {
@Override
public int getItemViewType(int position) {
- if (canShowAdAtPosition(position)) {
- int adPos = getAdIndex(position);
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
+ int adPos = AdapterCalculator.getAdIndex(position);
NativeAd ad = adFetcher.getAdForIndex(adPos);
return ad instanceof NativeAppInstallAd ? VIEW_TYPE_AD_INSTALL : VIEW_TYPE_AD_CONTENT;
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItemViewType(origPos);
}
}
- /**
- * Translates an adapter position to an actual position within the underlying dataset.
- *
- * @param position the adapter position
- * @return the original position that the adapter position would have been without ads
- */
- protected int getOriginalContentPosition(int position) {
- int noOfAds = getAdsCountToPublish();
- // No of spaces for ads in the dataset, according to ad placement rules
- int adSpacesCount = position / (getNoOfDataBetweenAds() + 1);
- return position - Math.min(adSpacesCount, noOfAds);
- }
-
- /**
- * Determines if an ad can be shown at the given position. Checks if the position is for
- * an ad, using the preconfigured ad positioning rules; and if a native ad object is
- * available to place in that position.
- *
- * @param position the adapter position
- * @return true
if ads can
- */
- protected boolean canShowAdAtPosition(int position) {
-
- // Is this a valid position for an ad?
- // Is an ad for this position available?
- return isAdPosition(position) && isAdAvailable(position);
- }
-
- /**
- * Gets the ad index for this adapter position within the list of currently fetched ads.
- *
- * @param position the adapter position
- * @return the index of the ad within the list of fetched ads
- */
- private int getAdIndex(int position) {
- return (position / getNoOfDataBetweenAds()) - 1;
- }
-
- /**
- * Checks if adapter position is an ad position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad position, {@code false} otherwise
- */
- private boolean isAdPosition(int position) {
- return (position + 1) % (getNoOfDataBetweenAds() + 1) == 0;
- }
-
- /**
- * Checks if an ad is available for this position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad is available, {@code false} otherwise
- */
- private boolean isAdAvailable(int position) {
- int adIndex = getAdIndex(position);
- return position >= getNoOfDataBetweenAds()
- && adIndex >= 0
- && adIndex < getLimitOfAds()
- && adFetcher.getFetchedAdsCount() > adIndex;
- }
-
/**
* Destroys all currently fetched ads
*/
@@ -373,4 +330,9 @@ public void onAdCountChanged() {
notifyDataSetChanged();
}
+
+ @Override
+ public int getAdapterCount() {
+ return mAdapter.getCount();
+ }
}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapperInterface.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapperInterface.java
new file mode 100644
index 0000000..9a560d6
--- /dev/null
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobAdapterWrapperInterface.java
@@ -0,0 +1,8 @@
+package com.clockbyte.admobadapter;
+
+/**
+ * Created by FILM on 06.07.2016.
+ */
+public interface AdmobAdapterWrapperInterface {
+ int getAdapterCount();
+}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobFetcherBase.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobFetcherBase.java
index 86b6d86..f118d30 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobFetcherBase.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobFetcherBase.java
@@ -62,18 +62,18 @@ public void setAdmobReleaseUnitId(String admobReleaseUnitId) {
this.admobReleaseUnitId = admobReleaseUnitId;
}
- protected String testDeviceId;
+ protected ArrayList testDeviceId = new ArrayList();
/*
*Gets a test device ID. Normally you don't have to set it
*/
- public String getTestDeviceId() {
+ public ArrayList getTestDeviceIds() {
return testDeviceId;
}
/*
*Sets a test device ID. Normally you don't have to set it
*/
- public void setTestDeviceId(String testDeviceId) {
- this.testDeviceId = testDeviceId;
+ public void addTestDeviceId(String testDeviceId) {
+ this.testDeviceId.add(testDeviceId);
}
/**
@@ -133,11 +133,10 @@ protected void notifyObserversOfAdSizeChange() {
*/
protected synchronized AdRequest getAdRequest() {
AdRequest.Builder adBldr = new AdRequest.Builder();
- if(!TextUtils.isEmpty(getTestDeviceId()))
- adBldr.addTestDevice(getTestDeviceId());
+ for (String id : getTestDeviceIds()) {
+ adBldr.addTestDevice(id);
+ }
return adBldr.build();
- //.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
- // All emulators are added by default as test devices
}
/**
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobRecyclerAdapterWrapper.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobRecyclerAdapterWrapper.java
index e2eef57..b82cc46 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobRecyclerAdapterWrapper.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/AdmobRecyclerAdapterWrapper.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.support.v7.widget.RecyclerView;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +34,7 @@
*/
public class AdmobRecyclerAdapterWrapper
extends RecyclerView.Adapter>
- implements AdmobFetcherBase.AdmobListener {
+ implements AdmobFetcherBase.AdmobListener, AdmobAdapterWrapperInterface {
private final String TAG = AdmobRecyclerAdapterWrapper.class.getCanonicalName();
@@ -56,6 +57,17 @@ public void onChanged() {
AdmobFetcher adFetcher;
Context mContext;
+ private AdmobAdapterCalculator AdapterCalculator = new AdmobAdapterCalculator(this);
+ /*
+ * Gets an object which incapsulates transformation of the source and ad blocks indices
+ */
+ public AdmobAdapterCalculator getAdapterCalculator(){return AdapterCalculator;}
+ /*
+* Injects an object which incapsulates transformation of the source and ad blocks indices. You could override calculations
+* by inheritance of AdmobAdapterCalculator class
+*/
+ public void setAdapterCalculator(AdmobAdapterCalculator adapterCalculatordmob){AdapterCalculator = adapterCalculatordmob;}
+
private static final int VIEW_TYPE_COUNT = 2;
private static final int VIEW_TYPE_AD_CONTENT = 1;
@@ -64,18 +76,15 @@ public void onChanged() {
private final static int DEFAULT_NO_OF_DATA_BETWEEN_ADS = 10;
private final static int DEFAULT_LIMIT_OF_ADS = 3;
- private int mNoOfDataBetweenAds;
-
/*
- * Gets the number of your data items between ad blocks, by default it equals to 10.
- * You should set it according to the Admob's policies and rules which says not to
- * display more than one ad block at the visible part of the screen
- * so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
- */
+ * Gets the number of your data items between ad blocks, by default it equals to 10.
+ * You should set it according to the Admob's policies and rules which says not to
+ * display more than one ad block at the visible part of the screen
+ * so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
+ */
public int getNoOfDataBetweenAds() {
- return mNoOfDataBetweenAds;
+ return AdapterCalculator.getNoOfDataBetweenAds();
}
-
/*
* Sets the number of your data items between ad blocks, by default it equals to 10.
* You should set it according to the Admob's policies and rules which says not to
@@ -83,23 +92,31 @@ public int getNoOfDataBetweenAds() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public void setNoOfDataBetweenAds(int mNoOfDataBetweenAds) {
- this.mNoOfDataBetweenAds = mNoOfDataBetweenAds;
+ AdapterCalculator.setNoOfDataBetweenAds(mNoOfDataBetweenAds);
}
- private int mLimitOfAds;
+ public int getFirstAdIndex() {
+ return AdapterCalculator.getFirstAdIndex();
+ }
+ /*
+ * Sets the first ad block index (zero-based) in the adapter, by default it equals to 0
+ */
+ public void setFirstAdIndex(int firstAdIndex) {
+ AdapterCalculator.setFirstAdIndex(firstAdIndex);
+ }
/*
* Gets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public int getLimitOfAds() {
- return mLimitOfAds;
+ return AdapterCalculator.getLimitOfAds();
}
/*
* Sets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public void setLimitOfAds(int mLimitOfAds) {
- this.mLimitOfAds = mLimitOfAds;
+ AdapterCalculator.setLimitOfAds(mLimitOfAds);
}
private int mContentAdsLayoutId;
@@ -135,10 +152,17 @@ public void setInstallAdsLayoutId(int mInstallAdsLayoutId) {
}
/*
- *Sets a test device ID. Normally you don't have to set it
+ *Add a test device ID.
*/
+ public void addTestDeviceId(String testDeviceId) {
+ adFetcher.addTestDeviceId(testDeviceId);
+ }
+ /*
+*Sets a test device ID. Normally you don't have to set it
+*/
+ @Deprecated
public void setTestDeviceId(String testDeviceId) {
- adFetcher.setTestDeviceId(testDeviceId);
+ adFetcher.addTestDeviceId(testDeviceId);
}
/*
@@ -180,7 +204,7 @@ public void onBindViewHolder(ViewWrapper viewHolder, int position) {
AdViewHelper.bindContentAdView(lvi2, ad2);
break;
default:
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
mAdapter.onBindViewHolder(viewHolder, origPos);
}
}
@@ -251,20 +275,14 @@ public int getItemCount() {
No of currently fetched ads, as long as it isn't more than no of max ads that can
fit dataset.
*/
- int noOfAds = getAdsCountToPublish();
+ int noOfAds = AdapterCalculator.getAdsCountToPublish();
return mAdapter.getItemCount() > 0 ? mAdapter.getItemCount() + noOfAds : 0;
} else {
return 0;
}
}
- public int getAdsCountToPublish(){
- int noOfAds = Math.min(adFetcher.getFetchedAdsCount(),
- mAdapter.getItemCount() / getNoOfDataBetweenAds());
- return Math.min(noOfAds, getLimitOfAds());
- }
-
- /**
+ /**
* Gets the item in a given position in the dataset. If an ad is to be returned,
* a {@link NativeAd} object is returned.
*
@@ -273,11 +291,11 @@ public int getAdsCountToPublish(){
*/
public Object getItem(int position) {
- if (canShowAdAtPosition(position)) {
- int adPos = getAdIndex(position);
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
+ int adPos = AdapterCalculator.getAdIndex(position);
return adFetcher.getAdForIndex(adPos);
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItem(origPos);
}
}
@@ -289,78 +307,16 @@ public long getItemId(int position) {
@Override
public int getItemViewType(int position) {
- if (canShowAdAtPosition(position)) {
- int adPos = getAdIndex(position);
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
+ int adPos = AdapterCalculator.getAdIndex(position);
NativeAd ad = adFetcher.getAdForIndex(adPos);
return ad instanceof NativeAppInstallAd ? VIEW_TYPE_AD_INSTALL : VIEW_TYPE_AD_CONTENT;
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItemViewType(origPos);
}
}
- /**
- * Translates an adapter position to an actual position within the underlying dataset.
- *
- * @param position the adapter position
- * @return the original position that the adapter position would have been without ads
- */
- protected int getOriginalContentPosition(int position) {
- int noOfAds = getAdsCountToPublish();
- // No of spaces for ads in the dataset, according to ad placement rules
- int adSpacesCount = position / (getNoOfDataBetweenAds() + 1);
- return position - Math.min(adSpacesCount, noOfAds);
- }
-
- /**
- * Determines if an ad can be shown at the given position. Checks if the position is for
- * an ad, using the preconfigured ad positioning rules; and if a native ad object is
- * available to place in that position.
- *
- * @param position the adapter position
- * @return true
if ads can
- */
- protected boolean canShowAdAtPosition(int position) {
-
- // Is this a valid position for an ad?
- // Is an ad for this position available?
- return isAdPosition(position) && isAdAvailable(position);
- }
-
- /**
- * Gets the ad index for this adapter position within the list of currently fetched ads.
- *
- * @param position the adapter position
- * @return the index of the ad within the list of fetched ads
- */
- private int getAdIndex(int position) {
- return (position / getNoOfDataBetweenAds()) - 1;
- }
-
- /**
- * Checks if adapter position is an ad position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad position, {@code false} otherwise
- */
- private boolean isAdPosition(int position) {
- return (position + 1) % (getNoOfDataBetweenAds() + 1) == 0;
- }
-
- /**
- * Checks if an ad is available for this position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad is available, {@code false} otherwise
- */
- private boolean isAdAvailable(int position) {
- int adIndex = getAdIndex(position);
- return position >= getNoOfDataBetweenAds()
- && adIndex >= 0
- && adIndex < getLimitOfAds()
- && adFetcher.getFetchedAdsCount() > adIndex;
- }
-
/**
* Destroys all currently fetched ads
*/
@@ -380,4 +336,9 @@ public void onAdCountChanged() {
notifyDataSetChanged();
}
+
+ @Override
+ public int getAdapterCount() {
+ return mAdapter.getItemCount();
+ }
}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressAdapterWrapper.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressAdapterWrapper.java
index e864d4e..df3e0a2 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressAdapterWrapper.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressAdapterWrapper.java
@@ -19,20 +19,26 @@
import android.content.Context;
import android.database.DataSetObserver;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.BaseAdapter;
+import com.clockbyte.admobadapter.AdmobAdapterCalculator;
+import com.clockbyte.admobadapter.AdmobAdapterWrapperInterface;
import com.clockbyte.admobadapter.AdmobFetcherBase;
import com.clockbyte.admobadapter.R;
+import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.NativeExpressAdView;
/**
* Adapter that has common functionality for any adapters that need to show ads in-between
* other data.
*/
-public class AdmobExpressAdapterWrapper extends BaseAdapter implements AdmobFetcherBase.AdmobListener {
+public class AdmobExpressAdapterWrapper extends BaseAdapter implements AdmobFetcherBase.AdmobListener,
+ AdmobAdapterWrapperInterface {
private final String TAG = AdmobExpressAdapterWrapper.class.getCanonicalName();
@@ -59,14 +65,24 @@ public void onInvalidated() {
AdmobFetcherExpress adFetcher;
Context mContext;
+ private AdmobAdapterCalculator AdapterCalculator = new AdmobAdapterCalculator(this);
+ /*
+ * Gets an object which incapsulates transformation of the source and ad blocks indices
+ */
+ public AdmobAdapterCalculator getAdapterCalculator(){return AdapterCalculator;}
+ /*
+* Injects an object which incapsulates transformation of the source and ad blocks indices. You could override calculations
+* by inheritance of AdmobAdapterCalculator class
+*/
+ public void setAdapterCalculator(AdmobAdapterCalculator adapterCalculatordmob){AdapterCalculator = adapterCalculatordmob;}
private static final int VIEW_TYPE_COUNT = 1;
private static final int VIEW_TYPE_AD_EXPRESS = 1;
private final static int DEFAULT_NO_OF_DATA_BETWEEN_ADS = 10;
private final static int DEFAULT_LIMIT_OF_ADS = 3;
-
- private int mNoOfDataBetweenAds;
+ private static final AdSize DEFAULT_AD_SIZE = new AdSize(AdSize.FULL_WIDTH, 150);
+ private static final String DEFAULT_AD_UNIT_ID = "ca-app-pub-3940256099942544/1072772517";
/*
* Gets the number of your data items between ad blocks, by default it equals to 10.
@@ -75,9 +91,8 @@ public void onInvalidated() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public int getNoOfDataBetweenAds() {
- return mNoOfDataBetweenAds;
+ return AdapterCalculator.getNoOfDataBetweenAds();
}
-
/*
* Sets the number of your data items between ad blocks, by default it equals to 10.
* You should set it according to the Admob's policies and rules which says not to
@@ -85,52 +100,85 @@ public int getNoOfDataBetweenAds() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public void setNoOfDataBetweenAds(int mNoOfDataBetweenAds) {
- this.mNoOfDataBetweenAds = mNoOfDataBetweenAds;
+ AdapterCalculator.setNoOfDataBetweenAds(mNoOfDataBetweenAds);
}
- private int mLimitOfAds;
+ public int getFirstAdIndex() {
+ return AdapterCalculator.getFirstAdIndex();
+ }
+ /*
+ * Sets the first ad block index (zero-based) in the adapter, by default it equals to 0
+ */
+ public void setFirstAdIndex(int firstAdIndex) {
+ AdapterCalculator.setFirstAdIndex(firstAdIndex);
+ }
/*
* Gets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public int getLimitOfAds() {
- return mLimitOfAds;
+ return AdapterCalculator.getLimitOfAds();
}
/*
* Sets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public void setLimitOfAds(int mLimitOfAds) {
- this.mLimitOfAds = mLimitOfAds;
+ AdapterCalculator.setLimitOfAds(mLimitOfAds);
}
- private int mExpressAdsLayoutId;
+ private String mAdsUnitId;
/*
* Gets the res layout id for published express ads
*/
- public int getExpressAdsLayoutId() {
- return mExpressAdsLayoutId;
+ public String getAdsUnitId() {
+ return mAdsUnitId;
}
/*
* Sets the res layout id for published express ads
*/
- public void setExpressAdsLayoutId(int mExpressAdsLayoutId) {
- this.mExpressAdsLayoutId = mExpressAdsLayoutId;
+ public void setAdsUnitId(String mAdsUnitId) {
+ this.mAdsUnitId = mAdsUnitId;
+ }
+
+ /*
+ *Add a test device ID.
+ */
+ public void addTestDeviceId(String testDeviceId) {
+ adFetcher.addTestDeviceId(testDeviceId);
}
/*
*Sets a test device ID. Normally you don't have to set it
*/
+ @Deprecated
public void setTestDeviceId(String testDeviceId) {
- adFetcher.setTestDeviceId(testDeviceId);
+ adFetcher.addTestDeviceId(testDeviceId);
+ }
+
+ private AdSize mAdSize;
+
+ /*
+ * Gets ad size
+ */
+ public AdSize getAdSize() {
+ return mAdSize;
+ }
+
+ /*
+ * Sets ad size
+ */
+ public void setAdSize(AdSize mAdSize) {
+ this.mAdSize = mAdSize;
}
public AdmobExpressAdapterWrapper(Context context) {
setNoOfDataBetweenAds(DEFAULT_NO_OF_DATA_BETWEEN_ADS);
setLimitOfAds(DEFAULT_LIMIT_OF_ADS);
- setExpressAdsLayoutId(R.layout.adexpresslistview_item);
+ setAdsUnitId(DEFAULT_AD_UNIT_ID);
+ setAdSize(DEFAULT_AD_SIZE);
mContext = context;
adFetcher = new AdmobFetcherExpress(mContext);
@@ -152,17 +200,17 @@ public View getView(int position, View convertView, ViewGroup parent) {
}
return item;
default:
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getView(origPos, convertView, parent);
}
}
private NativeExpressAdView getExpressAdView(ViewGroup parent) {
- // Inflate a layout and add it to the parent ViewGroup.
- LayoutInflater inflater = (LayoutInflater) parent.getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- NativeExpressAdView adView = (NativeExpressAdView) inflater
- .inflate(getExpressAdsLayoutId(), parent, false);
+ NativeExpressAdView adView = new NativeExpressAdView(mContext);
+ adView.setAdSize(getAdSize());
+ adView.setAdUnitId(getAdsUnitId());
+ adView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
+ AbsListView.LayoutParams.WRAP_CONTENT));
return adView;
}
@@ -184,19 +232,13 @@ public int getCount() {
No of currently fetched ads, as long as it isn't more than no of max ads that can
fit dataset.
*/
- int noOfAds = getAdsCountToPublish();
+ int noOfAds = AdapterCalculator.getAdsCountToPublish();
return mAdapter.getCount() > 0 ? mAdapter.getCount() + noOfAds : 0;
} else {
return 0;
}
}
- public int getAdsCountToPublish(){
- int noOfAds = Math.min(adFetcher.getFetchedAdsCount(),
- mAdapter.getCount() / getNoOfDataBetweenAds());
- return Math.min(noOfAds, getLimitOfAds());
- }
-
/**
* Gets the item in a given position in the dataset. If an ad is to be returned,
* a {@link NativeExpressAdView} object is returned.
@@ -207,11 +249,11 @@ public int getAdsCountToPublish(){
@Override
public Object getItem(int position) {
- if (canShowAdAtPosition(position)) {
- int adPos = getAdIndex(position);
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
+ int adPos = AdapterCalculator.getAdIndex(position);
return adFetcher.getAdForIndex(adPos);
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItem(origPos);
}
}
@@ -228,75 +270,14 @@ public int getViewTypeCount() {
@Override
public int getItemViewType(int position) {
- if (canShowAdAtPosition(position)) {
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
return VIEW_TYPE_AD_EXPRESS;
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItemViewType(origPos);
}
}
- /**
- * Translates an adapter position to an actual position within the underlying dataset.
- *
- * @param position the adapter position
- * @return the original position that the adapter position would have been without ads
- */
- protected int getOriginalContentPosition(int position) {
- int noOfAds = getAdsCountToPublish();
- // No of spaces for ads in the dataset, according to ad placement rules
- int adSpacesCount = position / (getNoOfDataBetweenAds() + 1);
- return position - Math.min(adSpacesCount, noOfAds);
- }
-
- /**
- * Determines if an ad can be shown at the given position. Checks if the position is for
- * an ad, using the preconfigured ad positioning rules; and if a native ad object is
- * available to place in that position.
- *
- * @param position the adapter position
- * @return true
if ads can
- */
- protected boolean canShowAdAtPosition(int position) {
-
- // Is this a valid position for an ad?
- // Is an ad for this position available?
- return isAdPosition(position) && isAdAvailable(position);
- }
-
- /**
- * Gets the ad index for this adapter position within the list of currently fetched ads.
- *
- * @param position the adapter position
- * @return the index of the ad within the list of fetched ads
- */
- private int getAdIndex(int position) {
- return (position / getNoOfDataBetweenAds()) - 1;
- }
-
- /**
- * Checks if adapter position is an ad position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad position, {@code false} otherwise
- */
- private boolean isAdPosition(int position) {
- return (position + 1) % (getNoOfDataBetweenAds() + 1) == 0;
- }
-
- /**
- * Checks if an ad is available for this position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad is available, {@code false} otherwise
- */
- private boolean isAdAvailable(int position) {
- int adIndex = getAdIndex(position);
- return position >= getNoOfDataBetweenAds()
- && adIndex >= 0
- && adIndex < getLimitOfAds();
- }
-
/**
* Destroys all currently fetched ads
*/
@@ -316,4 +297,9 @@ public void onAdCountChanged() {
notifyDataSetChanged();
}
+
+ @Override
+ public int getAdapterCount() {
+ return mAdapter.getCount();
+ }
}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressRecyclerAdapterWrapper.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressRecyclerAdapterWrapper.java
index 6d7ae71..7111543 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressRecyclerAdapterWrapper.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobExpressRecyclerAdapterWrapper.java
@@ -19,34 +19,34 @@
import android.content.Context;
import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import com.clockbyte.admobadapter.AdmobAdapterCalculator;
+import com.clockbyte.admobadapter.AdmobAdapterWrapperInterface;
import com.clockbyte.admobadapter.AdmobFetcherBase;
import com.clockbyte.admobadapter.R;
import com.clockbyte.admobadapter.RecyclerViewAdapterBase;
import com.clockbyte.admobadapter.ViewWrapper;
+import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.NativeExpressAdView;
/**
* Adapter that has common functionality for any adapters that need to show ads in-between
* other data.
*/
-public class AdmobExpressRecyclerAdapterWrapper
- extends RecyclerView.Adapter>
- implements AdmobFetcherBase.AdmobListener {
+public class AdmobExpressRecyclerAdapterWrapper extends RecyclerView.Adapter>
+ implements AdmobFetcherBase.AdmobListener, AdmobAdapterWrapperInterface {
private final String TAG = AdmobExpressRecyclerAdapterWrapper.class.getCanonicalName();
- private RecyclerViewAdapterBase mAdapter;
+ private RecyclerViewAdapterBase mAdapter;
- public RecyclerViewAdapterBase getAdapter() {
+ public RecyclerViewAdapterBase getAdapter() {
return mAdapter;
}
- public void setAdapter(RecyclerViewAdapterBase adapter) {
+ public void setAdapter(RecyclerViewAdapterBase adapter) {
mAdapter = adapter;
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
@@ -59,13 +59,24 @@ public void onChanged() {
AdmobFetcherExpress adFetcher;
Context mContext;
+ private AdmobAdapterCalculator AdapterCalculator = new AdmobAdapterCalculator(this);
+ /*
+ * Gets an object which incapsulates transformation of the source and ad blocks indices
+ */
+ public AdmobAdapterCalculator getAdapterCalculator(){return AdapterCalculator;}
+ /*
+* Injects an object which incapsulates transformation of the source and ad blocks indices. You could override calculations
+* by inheritance of AdmobAdapterCalculator class
+*/
+ public void setAdapterCalculator(AdmobAdapterCalculator adapterCalculatordmob){AdapterCalculator = adapterCalculatordmob;}
+
private static final int VIEW_TYPE_AD_EXPRESS = 1;
private final static int DEFAULT_NO_OF_DATA_BETWEEN_ADS = 10;
private final static int DEFAULT_LIMIT_OF_ADS = 3;
-
- private int mNoOfDataBetweenAds;
+ private static final AdSize DEFAULT_AD_SIZE = new AdSize(AdSize.FULL_WIDTH, 150);
+ private static final String DEFAULT_AD_UNIT_ID = "ca-app-pub-3940256099942544/1072772517";
/*
* Gets the number of your data items between ad blocks, by default it equals to 10.
@@ -74,7 +85,7 @@ public void onChanged() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public int getNoOfDataBetweenAds() {
- return mNoOfDataBetweenAds;
+ return AdapterCalculator.getNoOfDataBetweenAds();
}
/*
@@ -84,52 +95,86 @@ public int getNoOfDataBetweenAds() {
* so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
*/
public void setNoOfDataBetweenAds(int mNoOfDataBetweenAds) {
- this.mNoOfDataBetweenAds = mNoOfDataBetweenAds;
+ AdapterCalculator.setNoOfDataBetweenAds(mNoOfDataBetweenAds);
+ }
+
+ public int getFirstAdIndex() {
+ return AdapterCalculator.getFirstAdIndex();
}
- private int mLimitOfAds;
+ /*
+ * Sets the first ad block index (zero-based) in the adapter, by default it equals to 0
+ */
+ public void setFirstAdIndex(int firstAdIndex) {
+ AdapterCalculator.setFirstAdIndex(firstAdIndex);
+ }
/*
* Gets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public int getLimitOfAds() {
- return mLimitOfAds;
+ return AdapterCalculator.getLimitOfAds();
}
/*
* Sets the max count of ad blocks per dataset, by default it equals to 3 (according to the Admob's policies and rules)
*/
public void setLimitOfAds(int mLimitOfAds) {
- this.mLimitOfAds = mLimitOfAds;
+ AdapterCalculator.setLimitOfAds(mLimitOfAds);
}
- private int mExpressAdsLayoutId;
+ private String mAdsUnitId;
/*
* Gets the res layout id for published express ads
*/
- public int getExpressAdsLayoutId() {
- return mExpressAdsLayoutId;
+ public String getAdsUnitId() {
+ return mAdsUnitId;
}
/*
* Sets the res layout id for published express ads
*/
- public void setExpressAdsLayoutId(int mExpressAdsLayoutId) {
- this.mExpressAdsLayoutId = mExpressAdsLayoutId;
+ public void setAdsUnitId(String mAdsUnitId) {
+ this.mAdsUnitId = mAdsUnitId;
+ }
+
+ /*
+ *Add a test device ID.
+ */
+ public void addTestDeviceId(String testDeviceId) {
+ adFetcher.addTestDeviceId(testDeviceId);
}
/*
*Sets a test device ID. Normally you don't have to set it
*/
+ @Deprecated
public void setTestDeviceId(String testDeviceId) {
- adFetcher.setTestDeviceId(testDeviceId);
+ adFetcher.addTestDeviceId(testDeviceId);
+ }
+
+ private AdSize mAdSize;
+
+ /*
+ * Gets ad size
+ */
+ public AdSize getAdSize() {
+ return mAdSize;
+ }
+
+ /*
+ * Sets ad size
+ */
+ public void setAdSize(AdSize mAdSize) {
+ this.mAdSize = mAdSize;
}
public AdmobExpressRecyclerAdapterWrapper(Context context) {
setNoOfDataBetweenAds(DEFAULT_NO_OF_DATA_BETWEEN_ADS);
setLimitOfAds(DEFAULT_LIMIT_OF_ADS);
- setExpressAdsLayoutId(R.layout.adexpresslistview_item);
+ setAdsUnitId(DEFAULT_AD_UNIT_ID);
+ setAdSize(DEFAULT_AD_SIZE);
mContext = context;
adFetcher = new AdmobFetcherExpress(mContext);
@@ -138,11 +183,11 @@ public AdmobExpressRecyclerAdapterWrapper(Context context) {
@Override
public void onBindViewHolder(ViewWrapper viewHolder, int position) {
- if (viewHolder==null)
+ if (viewHolder == null)
return;
- if(viewHolder.getItemViewType()!=VIEW_TYPE_AD_EXPRESS){
- int origPos = getOriginalContentPosition(position);
+ if (viewHolder.getItemViewType() != VIEW_TYPE_AD_EXPRESS) {
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
mAdapter.onBindViewHolder(viewHolder, origPos);
}
}
@@ -154,18 +199,18 @@ public final ViewWrapper onCreateViewHolder(ViewGroup parent, int viewType) {
NativeExpressAdView item = getExpressAdView(parent);
adFetcher.setupAd(item);
adFetcher.fetchAd(item);
- return new ViewWrapper((V)item);
+ return new ViewWrapper((V) item);
default:
return mAdapter.onCreateViewHolder(parent, viewType);
}
}
private NativeExpressAdView getExpressAdView(ViewGroup parent) {
- // Inflate a layout and add it to the parent ViewGroup.
- LayoutInflater inflater = (LayoutInflater) parent.getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- NativeExpressAdView adView = (NativeExpressAdView) inflater
- .inflate(getExpressAdsLayoutId(), parent, false);
+ NativeExpressAdView adView = new NativeExpressAdView(mContext);
+ adView.setAdSize(getAdSize());
+ adView.setAdUnitId(getAdsUnitId());
+ adView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,
+ RecyclerView.LayoutParams.WRAP_CONTENT));
return adView;
}
@@ -187,19 +232,13 @@ public int getItemCount() {
No of currently fetched ads, as long as it isn't more than no of max ads that can
fit dataset.
*/
- int noOfAds = getAdsCountToPublish();
+ int noOfAds = AdapterCalculator.getAdsCountToPublish();
return mAdapter.getItemCount() > 0 ? mAdapter.getItemCount() + noOfAds : 0;
} else {
return 0;
}
}
- public int getAdsCountToPublish(){
- int noOfAds = Math.min(adFetcher.getFetchedAdsCount(),
- mAdapter.getItemCount() / getNoOfDataBetweenAds());
- return Math.min(noOfAds, getLimitOfAds());
- }
-
@Override
public long getItemId(int position) {
return position;
@@ -207,75 +246,14 @@ public long getItemId(int position) {
@Override
public int getItemViewType(int position) {
- if (canShowAdAtPosition(position)) {
+ if (AdapterCalculator.canShowAdAtPosition(position)) {
return VIEW_TYPE_AD_EXPRESS;
} else {
- int origPos = getOriginalContentPosition(position);
+ int origPos = AdapterCalculator.getOriginalContentPosition(position);
return mAdapter.getItemViewType(origPos);
}
}
- /**
- * Translates an adapter position to an actual position within the underlying dataset.
- *
- * @param position the adapter position
- * @return the original position that the adapter position would have been without ads
- */
- protected int getOriginalContentPosition(int position) {
- int noOfAds = getAdsCountToPublish();
- // No of spaces for ads in the dataset, according to ad placement rules
- int adSpacesCount = position / (getNoOfDataBetweenAds() + 1);
- return position - Math.min(adSpacesCount, noOfAds);
- }
-
- /**
- * Determines if an ad can be shown at the given position. Checks if the position is for
- * an ad, using the preconfigured ad positioning rules; and if a native ad object is
- * available to place in that position.
- *
- * @param position the adapter position
- * @return true
if ads can
- */
- protected boolean canShowAdAtPosition(int position) {
-
- // Is this a valid position for an ad?
- // Is an ad for this position available?
- return isAdPosition(position) && isAdAvailable(position);
- }
-
- /**
- * Gets the ad index for this adapter position within the list of currently fetched ads.
- *
- * @param position the adapter position
- * @return the index of the ad within the list of fetched ads
- */
- private int getAdIndex(int position) {
- return (position / getNoOfDataBetweenAds()) - 1;
- }
-
- /**
- * Checks if adapter position is an ad position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad position, {@code false} otherwise
- */
- private boolean isAdPosition(int position) {
- return (position + 1) % (getNoOfDataBetweenAds() + 1) == 0;
- }
-
- /**
- * Checks if an ad is available for this position.
- *
- * @param position the adapter position
- * @return {@code true} if an ad is available, {@code false} otherwise
- */
- private boolean isAdAvailable(int position) {
- int adIndex = getAdIndex(position);
- return position >= getNoOfDataBetweenAds()
- && adIndex >= 0
- && adIndex < getLimitOfAds();
- }
-
/**
* Destroys all currently fetched ads
*/
@@ -295,4 +273,9 @@ public void onAdCountChanged() {
notifyDataSetChanged();
}
+
+ @Override
+ public int getAdapterCount() {
+ return mAdapter.getItemCount();
+ }
}
diff --git a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobFetcherExpress.java b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobFetcherExpress.java
index f2c1f36..8584528 100644
--- a/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobFetcherExpress.java
+++ b/admobadapter/src/main/java/com/clockbyte/admobadapter/expressads/AdmobFetcherExpress.java
@@ -19,14 +19,10 @@
import android.content.Context;
import android.os.Handler;
-import android.text.TextUtils;
import android.util.Log;
-import android.view.View;
import com.clockbyte.admobadapter.AdmobFetcherBase;
-import com.clockbyte.admobadapter.R;
import com.google.android.gms.ads.AdListener;
-import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.NativeExpressAdView;
import java.lang.ref.WeakReference;
diff --git a/admobadapter/src/main/res/layout/adexpresslistview_item.xml b/admobadapter/src/main/res/layout/adexpresslistview_item.xml
deleted file mode 100644
index a16ffaa..0000000
--- a/admobadapter/src/main/res/layout/adexpresslistview_item.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
\ No newline at end of file
diff --git a/sampleapp/sampleapp.iml b/sampleapp/sampleapp.iml
index 7ee2ad7..7b3ac4d 100644
--- a/sampleapp/sampleapp.iml
+++ b/sampleapp/sampleapp.iml
@@ -64,14 +64,6 @@
-
-
-
-
-
-
-
-
@@ -80,6 +72,14 @@
+
+
+
+
+
+
+
+
diff --git a/sampleapp/src/main/AndroidManifest.xml b/sampleapp/src/main/AndroidManifest.xml
index c2f8e0b..cbc38bf 100644
--- a/sampleapp/src/main/AndroidManifest.xml
+++ b/sampleapp/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme" >
diff --git a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_ListView.java b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_ListView.java
index f44c06c..7f0c35a 100644
--- a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_ListView.java
+++ b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_ListView.java
@@ -5,6 +5,7 @@
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.clockbyte.admobadapter.AdmobAdapterWrapper;
+import com.google.android.gms.ads.MobileAds;
import java.util.ArrayList;
import java.util.Timer;
@@ -21,6 +22,10 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_listview);
+ //highly-recommended in Firebase docs to initialize things early as possible
+ //test_admob_app_id is different with unit_id! you could get it in your Admob console
+ MobileAds.initialize(getApplicationContext(), getString(R.string.test_admob_app_id));
+
initListViewItems();
initUpdateAdsTimer();
}
@@ -51,6 +56,8 @@ private void initListViewItems() {
// so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
adapterWrapper.setNoOfDataBetweenAds(10);
+ adapterWrapper.setFirstAdIndex(2);
+
//It's a test admob ID. Please replace it with a real one only when you will be ready to deploy your product to the Release!
//Otherwise your Admob account could be banned
//String admobUnitId = getResources().getString(R.string.banner_admob_unit_id);
diff --git a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_RecyclerView.java b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_RecyclerView.java
index 1421ea3..ce180d1 100644
--- a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_RecyclerView.java
+++ b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/MainActivity_RecyclerView.java
@@ -7,6 +7,7 @@
import android.widget.ArrayAdapter;
import com.clockbyte.admobadapter.AdmobRecyclerAdapterWrapper;
+import com.google.android.gms.ads.MobileAds;
import java.util.ArrayList;
import java.util.Timer;
@@ -23,6 +24,10 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_recycleview);
+ //highly-recommended in Firebase docs to initialize things early as possible
+ //test_admob_app_id is different with unit_id! you could get it in your Admob console
+ MobileAds.initialize(getApplicationContext(), getString(R.string.test_admob_app_id));
+
initRecyclerViewItems();
initUpdateAdsTimer();
}
@@ -53,6 +58,8 @@ private void initRecyclerViewItems() {
// so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
adapterWrapper.setNoOfDataBetweenAds(10);
+ adapterWrapper.setFirstAdIndex(2);
+
//It's a test admob ID. Please replace it with a real one only when you will be ready to deploy your product to the Release!
//Otherwise your Admob account could be banned
//String admobUnitId = getResources().getString(R.string.banner_admob_unit_id);
diff --git a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_ListView_Express.java b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_ListView_Express.java
index 98e297b..7c113bf 100644
--- a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_ListView_Express.java
+++ b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_ListView_Express.java
@@ -7,6 +7,9 @@
import com.clockbyte.admobadapter.expressads.AdmobExpressAdapterWrapper;
import com.clockbyte.admobadapter.sampleapp.R;
+import com.google.android.gms.ads.AdRequest;
+import com.google.android.gms.ads.AdSize;
+import com.google.android.gms.ads.MobileAds;
import java.util.ArrayList;
import java.util.Timer;
@@ -23,6 +26,10 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_listview);
+ //highly-recommended in Firebase docs to initialize things early as possible
+ //test_admob_app_id is different with unit_id! you could get it in your Admob console
+ MobileAds.initialize(getApplicationContext(), getString(R.string.test_admob_app_id));
+
initListViewItems();
initUpdateAdsTimer();
}
@@ -42,7 +49,8 @@ private void initListViewItems() {
//TODO it's important to set your test device ID (you can find it in LogCat after launching the debug session i.e. by word "test")
//if you launch app on emulator and experience some troubles
// try passing the constant AdRequest.DEVICE_ID_EMULATOR
- adapterWrapper.setTestDeviceId(getString(R.string.testDeviceID));//set an unique test device ID
+ adapterWrapper.addTestDeviceId(getString(R.string.testDeviceID));//set an unique test device ID
+ adapterWrapper.addTestDeviceId(AdRequest.DEVICE_ID_EMULATOR);
//TODO set the custom ads layout if you wish. NOTE you have to set your admob unit ID in this XML.
//It doesn't work for me if I set the unit ID in code with the method setAdUnitID() so it seems to be a bug
//adapterWrapper.setExpressAdsLayoutId(R.layout.adexpresslistview_item);
@@ -57,10 +65,11 @@ private void initListViewItems() {
// so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
adapterWrapper.setNoOfDataBetweenAds(10);
- //It's a test admob ID. Please replace it with a real one only when you will be ready to deploy your product to the Release!
- //Otherwise your Admob account could be banned
- //String admobUnitId = getResources().getString(R.string.banner_admob_unit_id);
- //adapterWrapper.setAdmobReleaseUnitId(admobUnitId);
+ adapterWrapper.setFirstAdIndex(2);
+ //due to the docs you should set the ad size before ads will be loaded
+ //AdSize.FULL_WIDTH x 150 is default size.
+ adapterWrapper.setAdSize(new AdSize(AdSize.FULL_WIDTH,150));
+ adapterWrapper.setAdsUnitId(getString(R.string.test_admob_express_unit_id));
lvMessages.setAdapter(adapterWrapper); // setting an AdmobAdapterWrapper to a ListView
diff --git a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_RecyclerView_Express.java b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_RecyclerView_Express.java
index 9150ef8..6c39e9f 100644
--- a/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_RecyclerView_Express.java
+++ b/sampleapp/src/main/java/com/clockbyte/admobadapter/sampleapp/express/MainActivity_RecyclerView_Express.java
@@ -8,6 +8,9 @@
import com.clockbyte.admobadapter.expressads.AdmobExpressRecyclerAdapterWrapper;
import com.clockbyte.admobadapter.sampleapp.R;
import com.clockbyte.admobadapter.sampleapp.RecyclerExampleAdapter;
+import com.google.android.gms.ads.AdRequest;
+import com.google.android.gms.ads.AdSize;
+import com.google.android.gms.ads.MobileAds;
import java.util.ArrayList;
import java.util.Timer;
@@ -24,6 +27,10 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_recycleview);
+ //highly-recommended in Firebase docs to initialize things early as possible
+ //test_admob_app_id is different with unit_id! you could get it in your Admob console
+ MobileAds.initialize(getApplicationContext(), getString(R.string.test_admob_app_id));
+
initRecyclerViewItems();
initUpdateAdsTimer();
}
@@ -43,7 +50,8 @@ private void initRecyclerViewItems() {
//TODO it's important to set your test device ID (you can find it in LogCat after launching the debug session i.e. by word "test")
//if you launch app on emulator and experience some troubles
// try passing the constant AdRequest.DEVICE_ID_EMULATOR
- adapterWrapper.setTestDeviceId(getString(R.string.testDeviceID));//set an unique test device ID
+ adapterWrapper.addTestDeviceId(getString(R.string.testDeviceID));//set an unique test device ID
+ adapterWrapper.addTestDeviceId(AdRequest.DEVICE_ID_EMULATOR);
//TODO set the custom ads layout if you wish. NOTE you have to set your admob unit ID in this XML.
//It doesn't work for me if I set the unit ID in code with the method setAdUnitID() so it seems to be a bug
//adapterWrapper.setExpressAdsLayoutId(R.layout.adexpresslistview_item);
@@ -58,10 +66,11 @@ private void initRecyclerViewItems() {
// so you should choose this parameter carefully and according to your item's height and screen resolution of a target devices
adapterWrapper.setNoOfDataBetweenAds(10);
- //It's a test admob ID. Please replace it with a real one only when you will be ready to deploy your product to the Release!
- //Otherwise your Admob account could be banned
- //String admobUnitId = getResources().getString(R.string.banner_admob_unit_id);
- //adapterWrapper.setAdmobReleaseUnitId(admobUnitId);
+ adapterWrapper.setFirstAdIndex(2);
+ //due to the docs you should set the ad size before ads will be loaded
+ //AdSize.FULL_WIDTH x 150 is default size.
+ adapterWrapper.setAdSize(new AdSize(AdSize.FULL_WIDTH,150));
+ adapterWrapper.setAdsUnitId(getString(R.string.test_admob_express_unit_id));
rvMessages.setAdapter(adapterWrapper); // setting an AdmobExpressRecyclerAdapterWrapper to a RecyclerView
diff --git a/sampleapp/src/main/res/values/strings.xml b/sampleapp/src/main/res/values/strings.xml
index 7ed638e..9d16040 100644
--- a/sampleapp/src/main/res/values/strings.xml
+++ b/sampleapp/src/main/res/values/strings.xml
@@ -2,4 +2,6 @@
admobadapter-sampleapp
ca-app-pub-xxx/xxx
6BA3752AF66F8D8553248A71886E648D
+ ca-app-pub-3940256099942544~3347511713
+ ca-app-pub-3940256099942544/1072772517