Click here to Skip to main content
15,889,863 members
Articles / Mobile Apps / Android

How to Add Banners into Android App and Not Overlap other UI Elements

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
30 Jun 2015CPOL6 min read 11.6K   4  
How to add banners into Android app and not overlap other UI elements

Banners are one of the most popular mobile advertisement formats. They don’t consume much space, as, for example, interstitial advertisements. And this allows developers to combine banners with other UI elements. Banners can be added to many app’s screens. If you read this article, you will find a method of how to add banners to your app, in such a way that banners will not overlap other UI elements. You need not change layout of XML and make much app’s code changes. Banner integration code is minimal. You can easily insert banners into ready app with only a few lines of code. Also, this method allows you to integrate banners in such a way that you can easily make advertisement free app version without complex code changes. The method described in the article is universal and can be used with different advertisement APIs. The article will be interesting for both novice and experienced developers. In order to understand the subject of the article, you do not need to have any in-depth knowledge. You just need to understand the basic concepts of the Android development. And experienced developers can find in it a ready-to-use solution that they can implement in their apps. But, advertisement service initialization, working with specific advertisement services and caching are not in scope of this article. To solve these issues, please refer to developer’s manual for your advertisement service.

An idea of this article was born when we had a situation with one of our Android apps. We had to add banners in several places, but we had to do so in a way that doesn't damage the look and feel of the app and not to overlap other UI elements with banners. We had written all app’s code, and we didn’t want to rewrite it. And because of this, we tried to make the banners integration as simple and correct as possible, and to not affect the work of the existing code. Another reason, because we needed to simplify the banners integration – the possibility to make release of paid version without ads. If we had integrated banners anywhere in the layout XML, it would greatly complicate the creation of ad-free version of UI.

To make it more clear about what I’m writing, please look at the following screen:

UI elements occupy the entire space of the screen. There is no empty space here. In this case, we can add a banner at the top or at the bottom. A variant of placing the banner at the bottom is more appropriate, because the banner will be far from other buttons, and user will not accidentally tap the banner trying to tap “Back” or “Done”. We need to place the banner below the photo GridView. And as the banner is downloaded over the network, it may not always be available. If the banner is not downloaded, it will be empty space at the bottom. And it will look ugly, as UI design defect. If we place the banner over GridView – it will overlap a part of photos create inconvenience for a user, which is also unacceptable.

To better understand it, you can install our free app BMEX. You can find it here https://play.google.com/store/apps/details?id=com.bitgriff.bmex. In BMEX, please, tap “Send” and then select “Photo” or “Video” and wait a bit until ads are loaded.

So, we formulate our task as: we need to make UI without additional empty space. And when the banner is loaded – dynamically add margin at the bottom and show the banner. On the other hand, we need to make the banner placement code as simple as possible, without any complex initializations. E.g. passing UI elements’ ids or ViewGroup references is not appropriate. Inserting banners into layout XML of every screen – is also not appropriate, because it requires severe changes. An ideal banner placement code must look like:

Java
Ads.showBottomBanner(activity);

Only one line of code, only one method call. Method gets reference to an Activity in which the banner will be placed. This code can be easily inserted into Activity’s onCreate method.

In order to implement this, we need to get access to Activity’s ContentView. ContentView is a ViewGroup in which all Activity’s UI elements are contained. There is no ContentView direct access method in the Activity class. But, thanks to StackOverflow user nickes, we have found a solution. You can find it here. We need a reference to a Window in which the Activity resides. Window has DecorView, and DecorView contains the ContentView.

So, we need to get Activity’s Window, then get DecorView, then get ContentView, then get a first child of ContentView. And change padding of this first child. The code can be found below:

Java
public static void setupContentViewPadding(Activity activity, boolean top, int margin) {
	View view = ((ViewGroup) activity.getWindow().getDecorView().findViewById
                    (android.R.id.content)).getChildAt(0);
	if (top)
		view.setPadding(view.getPaddingLeft(), margin, view.getPaddingRight(), view.getPaddingBottom());
	else
		view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), margin);
}

We have found a solution to dynamically add padding. And now we need to add the banner itself. Various ad services has different APIs. Some APIs has banner View that can be created and added to ViewGroup. But, some APIs have no access to banner’s View, and have only method that will show the banner. Let's consider both these variants.

API with Banner View

Let’s call this view class name Banner. (Please, refer to your ad API developers’ manual for details about its name and how to instantiate it). First, we need to create Banner view:

Java
final Banner banner = new Banner(activity);

Then, we setup event listener to receive banner loaded event (and, again, this is example code. For actual listener name and how to set it up, please your ad API developers’ guide):

Java
banner.setBannerListener(new BannerListener() {
		@Override
		public void onReceiveAd(View view) {
                        // get height of the banner view.
		        int height = banner.getHeight();

                        // if you have activity margins, subtract it. 
                        // If you don't have - you can remove the next line.
		        height -= activity.getResources().getDimensionPixelSize
                              (R.dimen.activity_vertical_margin);
					
                        // change bottom padding
			setupContentViewPadding(activity, true, height);
		}
	});

When banner is loaded, we call setupContentViewPadding. It will dynamically add space at bottom.

Then, we add our banner to Window.
We will add it above ContentView with existing UI elements. Window has addContentView method for this:

Java
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
			FrameLayout.LayoutParams.MATCH_PARENT, 
			height);//  Utils.toDIP(activity, BANNER_HEIGHT));

layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
activity.getWindow().addContentView(banner, layoutParams);

API Without Banner View

We don’t have banner view and we can’t create and add it explicitly. But, we have API that has methods, like showBanner.

I’ll call ads service API class – AdAPI. You can replace it with your actual ads service API class name. In this case, the banner placement code will look like (and again, this is not real code. Please, refer your ad API developers' guide for details about class names and how to use them):

Java
Ad banner = AdAPI.loadBanner();
banner.addListener(new AdListener() {
     public void adLoaded() {
            // add bottom padding, when banner is loaded.
            setupContentViewPadding(activity, true, BANNER_HEIGHT);
     }
});

When BANNER_HEIGHT is a constrant with banner height value;
Here are some issues. You need to know or setup explicitly the banner’s height through ad service administration interface. We had this problem, when we ran our app on 3.7 inch smartphone and 10.1 inch tablet. Banner sizes were different. On smartphone, the app looks fine, but on tablet, the banner was so big that it consumed too much UI space.

Result


As you can see, banner is shown and it doesn’t overlap any UI elements. Space at the bottom is added dynamically.

This is what we required.

To see how it works, you can run our free app BMEX. You can find it here https://play.google.com/store/apps/details?id=com.bitgriff.bmex. You need to tap “Send”, then tap “Photo” or “Video”, and wait a bit until ads are loaded.

Usage

Summarizing all that is written above, I will describe how to integrate this into your app.

Ads class.

Java
public class Ads {
	// replace it with your actual value
	final private static int BANNER_HEIGHT = 75;

	public static void showBottomBanner(Activity activity)  {
		// replace with your actual ad API code

		final Banner banner = new Banner(activity);

		banner.setBannerListener(new BannerListener() {
			@Override
			public void onReceiveAd(View view) {
	                        // get height of the banner view.
			        int height = banner.getHeight();

                        	// if you have activity margins, subtract it. 
                            // If you don't have - you can remove the next line.
			        height -= activity.getResources().getDimensionPixelSize
                                           (R.dimen.activity_vertical_margin);
					
	                        // change bottom padding
				setupContentViewPadding(activity, true, height);
			}
		});

		FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
				FrameLayout.LayoutParams.MATCH_PARENT, 
				height);//  Utils.toDIP(activity, BANNER_HEIGHT));

		layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
		activity.getWindow().addContentView(banner, layoutParams);
	}

	public static void setupContentViewPadding(Activity activity, boolean top, int margin) {
		View view = ((ViewGroup) activity.getWindow().getDecorView().findViewById
                       (android.R.id.content)).getChildAt(0);
		if (top)
			view.setPadding(view.getPaddingLeft(), margin, view.getPaddingRight(), 
                               view.getPaddingBottom());
		else
			view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), 
                           view.getPaddingRight(), margin);
	}
}

Banner placement can be made by Ads.showBottomBanner(this) call from Activity’s onCreate method.

Just replace code in showBottomBanner method with your ad API calls.

Summary

In the article, I described a method of how to easily and correctly integrate banners into Android app. There are more banner placement types. For example: take the first screen in the article and place banner between photos, not at the bottom. I hope the article was useful for you. Please post your suggestions as comments. Thank you for your attention. I wish you success in development!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO BitGriff LLC
Russian Federation Russian Federation
My name is Andrey Moskvichev.

I'm a software developer with more than 14 years of programming experience.

I specialize in networking, Unix systems (Linux, FreeBSD), mobile programming, computer graphics, software architecture, reverse engineering, data processing systems, AI, computer vision.

I'm interested in all new cutting edge technologies.

Comments and Discussions

 
-- There are no messages in this forum --