安卓应用中如何获取AdMob横幅广告出现时的高度

9

我已成功地将adMob横幅添加到我的应用程序中。当横幅出现时,我需要获取其高度以便调整所有布局元素的大小。我正在使用正确触发的onReceivedAd事件。但是,alturaBanner等于0。那么,如何获取它的高度?谢谢。

   /** 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();
    }
5个回答

25

在横幅被添加到布局之前,您可以获得任何类型横幅的高度。

int heightPixels = AdSize.SMART_BANNER.getHeightInPixels(this);
或者
int heightPixels = AdSize.FULL_BANNER.getHeightInPixels(myContext);

或适用于DIP

int heightDP = AdSize.BANNER.getHeight();

所以根据您的需求,您可以这样做:

/** 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();
}

只需将 AdSize.BANNER 更改为您正在使用的广告横幅类型,例如 AdSize.SMART_BANNER

广告尺寸获取高度


2
目前,AdSize.SMART_BANNER.getHeight(this); 是无效的,而 getHeight() 正在返回无意义的值(在我的情况下是 -2)。 - Fran Marzoa
AdSize.SMART_BANNER.getHeightInPixels(context)非常好用,因此我可以在广告加载时动态调整布局。该函数中的内部代码实际上是智能横幅所示的相同计算 https://stackoverflow.com/a/53061092/513479。 - txedo

6

在 View 准备好之前获取它的高度将始终返回 0。使用下面的代码可以获取其正确的大小,无论使用哪种设备/屏幕:

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);
}

在给定的可运行代码中,您可以查询视图的实际大小。或者,如果您希望,可以使用addOnGlobalLayoutListener而不是addOnPreDrawListener。另一种方法是使用onWindowFocusChanged(并检查hasFocus == true),但这并不总是最好的方法(仅用于简单的视图创建,而不是动态创建)。编辑:runJustBeforeBeingDrawn的替代方法:https://dev59.com/i2865IYBdhLWcg3whO3E#28136027

之前的答案对我有用,但是这种方法也可以应用!谢谢,+1。 - Jaume
1
之前的答案可能在某些设备上无法使用,也可能在未来的设备上无法使用。我的答案更通用,适用于任何视图和任何广告框架 - 如果您选择了不同的广告框架,它仍将适用于您。 - android developer
我认为这个答案不仅比其他答案更好,而且在原始问题“如何获取adMob横幅高度”方面也更准确。 - Fran Marzoa
@androiddeveloper 我遇到了一个严重的问题。当广告出现时,即adView.setVisibilit(View.Visible)时,我通过编程方式添加的片段视图会消失(可能被销毁)。有什么想法吗? - Muhammad Babar
@MuhammadBabar 我需要更多信息。你能否请开一个新的问题线程,提供更多信息(包括代码和布局),并给我一个链接?一旦我理解了你的意思,也许我就能帮助你了。 - android developer
显示剩余2条评论

2
如果您使用智能横幅类型来显示广告横幅,则无需等待出现广告视图即可获取adMob横幅高度。请使用智能横幅,因为它会根据设备大小自动决定广告的高度,并使用屏幕的全宽来显示广告。
从android开发人员的网站中可以了解到:(网址)“智能横幅是广告单元,在任何屏幕大小和不同设备上都可以呈现全屏广告横幅。智能横幅通过“聪明地”检测当前方向下手机的宽度,并使广告视图具有该大小,帮助解决了不同设备之间越来越多的屏幕碎片化问题。”
提供三种广告高度(以dp,密度独立像素为单位): 32 - 在设备的屏幕高度小于400时使用 50 - 在设备的屏幕高度在400到720之间时使用 90 - 在设备的屏幕高度大于720时使用
现在,获取AdView的高度并调整您想要放置横幅广告的布局的边距。一旦广告加载完成(通过覆盖onAdLoaded API),您可以使用以下方法来了解广告的高度:
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);
}

2
我使用以下方法获取AdView的高度:
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() 在全局布局状态或视图树中的视图可见性发生变化时被触发。


0

当AdMob无法接收广告或接收到空广告(高度=0)时,我有同样的需求能够显示自己的广告。

我使用以下代码,基于AdView扩展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
    }
});

'onLayoutChange'中的代码每次Admob接收到新广告时都会执行。

编辑:我的答案不正确,因为该方法是在API 11中添加的...我改为使用上一个答案中解释的'onPreDraw()'。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接