1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AdMob バナー広告の読み込み時にプレースホルダーを表示する

Posted at

課題

AndroidでAdMobバナー広告はアダプティブ バナー使用します。
よくある広告バナーをアプリ上部or下部に常時表示するアプリでは、リンク先の通り以下のように実装します。(レイアウトの呼び出しはDataBindingを使用しています。)

MainActivity
class MainActivity : AppCompatActivity(R.layout.activity_main) {
    ...
    private lateinit var adView: AdView
    private val adSize: AdSize
        get() {
            val display = windowManager.defaultDisplay
            val outMetrics = DisplayMetrics()
            display.getMetrics(outMetrics)

            val density = outMetrics.density

            var adWidthPixels = binding.adViewContainer.width.toFloat()
            if (adWidthPixels == 0f) {
                adWidthPixels = outMetrics.widthPixels.toFloat()
            }

            val adWidth = (adWidthPixels / density).toInt()
            return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        setupAdMob()
        ...
    }

    private fun setupAdMob() {
        MobileAds.initialize(this)
        adView = AdView(this)
        binding.adViewContainer.addView(adView)
        loadBanner()
    }

    private fun loadBanner() {
        adView.adUnitId = getString(R.string.banner_ad_unit_id)
        adView.adSize = adSize

        val adRequest = AdRequest.Builder().build()
        adView.loadAd(adRequest)
    }
}
activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >

        <!-- ヘッダー固定広告のためのコンテナ -->
        <FrameLayout
            android:id="@+id/ad_view_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

        <!-- コンテンツ領域 -->
        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph"
            />

    </LinearLayout>

</layout>

レイアウトの構築と広告ロードでは広告ロードの方が遅いため、広告ロードされるまでadViewContainerはサイズ0で表示されず、ロード完了時に表示領域が現れることになります。これでは突然広告が表示され不快な表示になったり、コンテンツ領域のサイズが変わるため混乱をきたします。

解決: プレースホルダーの表示

広告がロードされるまでの間プレースホルダーを表示して違和感のないレイアウトにします。
loadBanner関数にプレースホルダー表示を追加します。

MainActivity
class MainActivity : AppCompatActivity(R.layout.activity_main) {
    ...
    private fun loadBanner() {
        adView.adUnitId = getString(R.string.banner_ad_unit_id)
        adView.adSize = adSize
        val adRequest = AdRequest.Builder().build()
        adView.loadAd(adRequest)

        // プレースホルダー用のViewをadViewContainerに追加
        val placeholderView = adPlaceHolderView(this, adView.adSize)
        binding.adViewContainer.addView(placeholderView)

        // 広告ロード完了時にプレースホルダーを除去
        adView.adListener = object : AdListener() {
            override fun onAdLoaded() {
                binding.adViewContainer.removeView(placeholderView)
                adView.adListener = null
            }
        }
    }
}

fun adPlaceHolderView(context: Context, adSize: AdSize): View {
    return View(context).apply {
        val widthInPixels = adSize.getWidthInPixels(context)
        val heightInPixels = adSize.getHeightInPixels(context)
        layoutParams = ViewGroup.LayoutParams(widthInPixels, heightInPixels)
        setBackgroundColor(ContextCompat.getColor(context, R.color.grey400))
    }
}

表示する広告サイズが事前に分かっていれば静的にサイズをしても良いですが、アダプティブバナー(前身のスマートバナーも)アプリの表示サイズに応じて動的に広告サイズが変わります。したがって、AdSizeからこれから表示される広告サイズを取得することで、適切なサイズのプレースホルダーを表示できます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?