9

I am adding an adMob banner to my app successfully. When banner appears I need to get its height in order to resize all layout elements. I am using the event onReceivedAd, that is properly fired. However, alturaBanner is = 0. Then, how to get its height? thank you.

   /** Called when an ad is received. */
    @Override
    public void onReceiveAd(Ad ad) 
    {
        adView.setVisibility(View.VISIBLE);

        int alturaBanner = adView.getHeight();

        RelativeLayout.LayoutParams params1 = (android.widget.RelativeLayout.LayoutParams) browse2
        .getLayoutParams();

        params1.setMargins(0, alturaBanner, 0, 0);

      Log.d(LOG_TAG, "onReceiveAd");
      Toast.makeText(this, "onReceiveAd", Toast.LENGTH_SHORT).show();
    }
Jaume
  • 3,672
  • 19
  • 60
  • 119

5 Answers5

25

You can get the height of any type of banner before it is even added to the layout.

int heightPixels = AdSize.SMART_BANNER.getHeightInPixels(this);

or

int heightPixels = AdSize.FULL_BANNER.getHeightInPixels(myContext);

or for DIP's

int heightDP = AdSize.BANNER.getHeight();

So for your need, you could do this:

/** Called when an ad is received. */
@Override
public void onReceiveAd(Ad ad) 
{
    adView.setVisibility(View.VISIBLE);

    int alturaBanner = AdSize.BANNER.getHeight(); // This gets the adsize, even if the view is not inflated. 

    RelativeLayout.LayoutParams params1 = (android.widget.RelativeLayout.LayoutParams) browse2
    .getLayoutParams();

    params1.setMargins(0, alturaBanner, 0, 0);

  Log.d(LOG_TAG, "onReceiveAd");
  Toast.makeText(this, "onReceiveAd", Toast.LENGTH_SHORT).show();
}

Just change AdSize.BANNER to AdSize.SMART_BANNER or whatever banner type your using.

Add Sizes Get Height

kj007
  • 6,073
  • 4
  • 29
  • 47
XdebugX
  • 331
  • 3
  • 5
  • 2
    As of now, AdSize.SMART_BANNER.getHeight(this); is not valid, and getHeight() is returning nonsense values (-2 in my case). – Fran Marzoa Aug 16 '17 at 15:35
  • `AdSize.SMART_BANNER.getHeightInPixels(context)` works like a charm so I can adjust my layout at runtime when the ad is loaded. The inner code in that function is in fact the same calculation shown here for smart banners https://stackoverflow.com/a/53061092/513479 – txedo Jun 06 '21 at 15:55
6

getting the height of the view before it was prepared will always return you 0 . use the next code in order to get its correct size , no matter which device/screen you have:

private static void runJustBeforeBeingDrawn(final View view, final Runnable runnable)
{
    final ViewTreeObserver vto = view.getViewTreeObserver();
    final OnPreDrawListener preDrawListener = new OnPreDrawListener()
    {
        @Override
        public boolean onPreDraw()
        {
            runnable.run();
            final ViewTreeObserver vto = view.getViewTreeObserver();
            vto.removeOnPreDrawListener(this);
            return true;
        }
    };
    vto.addOnPreDrawListener(preDrawListener);
}

inside the given runnable , you can query the real size of the view.

alternatively , you can use addOnGlobalLayoutListener instead of addOnPreDrawListener if you wish.

another approach is to use onWindowFocusChanged (and check that hasFocus==true) , but that's not always the best way ( only use for simple views-creation, not for dynamic creations)

EDIT: Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • previous answer work for me but also this method could be applied! thanks, +1 – Jaume May 03 '12 at 14:44
  • 1
    previous answer might not work on some devices and also possible future devices . my answer is more generic and will work for any view , and for any ad framework you use - if you ever choose a different ad framework , it will still work for you . – android developer May 03 '12 at 15:18
  • I think this answer is not only better than the other one, it is also more acurated given the original question, that was "how to get adMob banner height". – Fran Marzoa Jul 25 '12 at 18:03
  • yes , an alternative would be to use "addOnGlobalLayoutListener" . – android developer Jul 25 '12 at 18:07
  • @androiddeveloper i'm facing a serious problem. When ads appear i.e adView.setVisibilit(View.Visible). The views in my fragment that i have added programmatically gets disappeared (may be destroyed) any idea? – Muhammad Babar Aug 23 '14 at 17:18
  • @MuhammadBabar I need more information. Can you please make a new question thread, put there some more information (and code&layout) and give me a link to it? maybe I will be able to help you once I understand what you mean. – android developer Aug 23 '14 at 17:39
  • @androiddeveloper I am facing a similar problem, when my admob banner ad is received and its view is set to visible (and also sometimes during ad transitions), it makes the screen to flicker for a moment, the fragment on top disappears for just a moment then it returns to normal, what could it be – Felipe May 29 '20 at 23:56
2

I use the following method to get AdView's height:

adView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int height = adView.getHeight();
        if (height > 0) {
            // now the height is gotten, you can do things you want
        }
    }
});

onGlobalLayout() is triggered when the global layout state or the visibility of views within the view tree changes.

Brian
  • 12,145
  • 20
  • 90
  • 153
2

Actually, you don't need to wait for appearance of adview to get adMob banner height if you are using smart banner type for showing banner ads.

Use Smart banner as it automatically decides the height of ad based on device size. Use full width of screen to show the ad.

From android developers site:

Smart Banners are ad units that will render screen-wide banner ads on any screen size across different devices in either orientation. Smart Banners help deal with increasing screen fragmentation across different devices by "smartly" detecting the width of the phone in its current orientation, and making the ad view that size.

Three ad heights (in dp, density-independent pixel) are available:

32 - used when the screen height of a device is less than 400
50 - used when the screen height of a device is between 400 and 720 90 - used when the screen height of a device is greater than 720

Now, get the height of AdView and adjust the margin of the layout where you wish to place the banner ad. Once the ad is loaded (by overriding on onAdLoaded API), you know the height using below method:

public static int getAdViewHeightInDP(Activity activity) {
    int adHeight = 0;

    int screenHeightInDP = getScreenHeightInDP(activity);
    if (screenHeightInDP < 400)
        adHeight = 32;
    else if (screenHeightInDP <= 720)
        adHeight = 50;
    else
        adHeight = 90;

    return adHeight;
}

public static int getScreenHeightInDP(Activity activity) {
    DisplayMetrics displayMetrics = ((Context) activity).getResources().getDisplayMetrics();

    float screenHeightInDP = displayMetrics.heightPixels / displayMetrics.density;

    return Math.round(screenHeightInDP);
}
Community
  • 1
  • 1
Green goblin
  • 9,898
  • 13
  • 71
  • 100
0

I had the same need to be able to display my own ads when AdMob fails to receive an ad or receives an empty ad (height=0).

I use the following code based on the fact that an AdView extends RelativeLayout:

mAdMobView = new AdView(pActivity, AdSize.SMART_BANNER, Constants.ADMOB_AD_UNIT_ID);
mAdMobView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(final View pV, final int pLeft, final int pTop, final int pRight, final int pBottom, final int pOldLeft, final int pOldTop, final int pOldRight, final int pOldBottom) {
        final float lAdHeight = mAdMobView.getHeight();
        if (lAdHeight == 0) {
            Debug.i(LOG_TAG, "mAdMobView.onLayoutChange(...) mAdMobView.height='" + lAdHeight + "'. AdMob returned an empty ad !");
            // Show custom ads
        } else {
            Debug.d(LOG_TAG, "mAdMobView.onLayoutChange(...) mAdMobView.height='" + lAdHeight + "'");
            // Make AdView visible
        }
    }
});
mAdMobView.setAdListener(new AdListener() {
    @Override public void onReceiveAd(final Ad pAd) {
        Debug.d(LOG_TAG, "onReceiveAd(...) AdMob ad received (mAdMobView.visibility='" + mAdMobView.getVisibility() + "').");
    }
    @Override public void onPresentScreen(final Ad pAd) {
        Debug.d(LOG_TAG, "onPresentScreen(...)");
    }
    @Override public void onLeaveApplication(final Ad pAd) {
        Debug.d(LOG_TAG, "onLeaveApplication(...)");
    }
    @Override public void onDismissScreen(final Ad pAd) {
        Debug.d(LOG_TAG, "onDismissScreen(...)");
    }

    @Override
    public void onFailedToReceiveAd(final Ad pAd, final ErrorCode pErrorCode) {
        Debug.i(LOG_TAG, "onFailedToReceiveAd(...) AdMob ad error (" + pErrorCode + ").");
        // Show custom ads
    }
});

The code in 'onLayoutChange' is executed every time Admob receives a new ad.

EDIT: My answer is not proper since this method was added with the API 11... I changed it for the use of onPreDraw() as explained in the previous answer.

Florian
  • 389
  • 1
  • 4
  • 15