Jetpack Compose 中的 Admob 原生广告?

问题描述 投票:0回答:1

我正在尝试从 adMob 实现一个基本的原生广告,以适应我在 Jetpack Compose 中的应用程序的设计,但我不明白 onClick 应该如何处理。

我知道使用 Viewbound 是可能的,但也必须有 Jetpack Compose 方式,因为这应该是 android 开发的未来。

我的完整可组合项:

object Advertising {
        var currentImageAd: NativeAd? by mutableStateOf(null)
    }
    
    @Composable
    fun ImageAd(modifier: Modifier = Modifier, adId: String, nativeAd: NativeAd?, setNativeAd: (NativeAd?) -> Unit) {
        val context = LocalContext.current
        var iconPainter = rememberAsyncImagePainter(
            model = ImageRequest.Builder(LocalContext.current)
                .data(nativeAd?.icon)
                .size(coil.size.Size.ORIGINAL)
                .build()
        )
    
        DisposableEffect(Unit) {
            val adLoader = AdLoader.Builder(context, adId)
                .forNativeAd { ad ->
                    if (nativeAd == null) {
                        setNativeAd(ad)
                    }
                }
                .withAdListener(object : AdListener() {
                    override fun onAdFailedToLoad(loadAdError: LoadAdError) {
                    }
                })
                .withNativeAdOptions(NativeAdOptions.Builder().build())
                .build()
    
            adLoader.loadAd(AdRequest.Builder().build())
    
            onDispose {
    
            }
        }
    
        nativeAd?.let { adData ->
            Box.SimpleBox(modifier,
                icon = R.drawable.advertisement,
                iconColor = colors.ad,
                headline = adData.headline,
                body = adData.body
            ) {
                Row(modifier = Modifier.height(IntrinsicSize.Max), horizontalArrangement = Arrangement.spacedBy(Padding.ContentSeparation.standard)) {
                    Image(painter = iconPainter,
                                contentDescription = null,
                                modifier = Modifier
                                    .fillMaxHeight()
                                    .aspectRatio(1f)
                            )
                    Button_Basic(shape = Shapes.tight, 
                         color = colors.ad, 
                         text = adData.callToAction ?:"Mehr", 
                         icon = R.drawable.web_exit, 
                         onClick = { 
                               //What to call here? 
                         })
                }
            }
        }
}

Box.SimpleBox
只是一个带有圆角的 Box Container,而
Button_Basic
则是一个带有文本的可点击框。广告标题、正文和 callToAction 文本均已正确加载并显示,但我不明白您应该如何让 onClick 工作。

AdMob Sdk 似乎通过自动使用广告资源来处理 Xml 中传统视图的 onClick,但它不知道如何让它在 Compose 中工作。另外,无法为本应可自定义的原生广告创建自定义按钮似乎很奇怪。

这在 Compose 中是不可能的吗?我需要用 XML 编写广告代码,或者我该如何解决这个问题?

android xml view android-jetpack-compose admob
1个回答
0
投票

Jetpack Compose 中没有对 NativeAd 的直接支持,因此我们必须手动完成所有操作。

首先我们将在 Jetapck Compose 中使用典型的基于 XML 的系统

所以只需在 build.gradle(app-module) 中启用它即可

添加依赖

implementation "androidx.compose.ui:ui-viewbinding:1.6.0-rc01"

启用功能

buildFeatures {
        viewBinding = true
    }

在 res/layout 文件夹中创建布局

layout_native_ad_medium.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/ad_background_color">

    <com.google.android.gms.ads.nativead.NativeAdView
        android:id="@+id/nativeAdView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="invisible">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:minHeight="60dp">

            <com.google.android.gms.ads.nativead.AdChoicesView
                android:id="@+id/adChoice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/ad_rounded_corners_shape"
                android:paddingHorizontal="4dp"
                android:paddingVertical="1dp"
                android:text="Ad"
                android:textColor="@color/white"
                android:textSize="10sp"
                android:textStyle="bold"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:ignore="SmallSp" />

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                app:layout_constraintGuide_begin="5dp" />

            <com.google.android.gms.ads.nativead.MediaView
                android:id="@+id/mv_content"
                android:layout_width="0dp"
                android:layout_height="130dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginHorizontal="16dp"
                android:layout_marginTop="5dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@id/guideline" />

            <ImageView
                android:id="@+id/iv_app_icon"
                android:layout_width="45dp"
                android:layout_height="45dp"
                android:layout_marginStart="16dp"
                android:layout_marginTop="10dp"
                android:adjustViewBounds="true"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/mv_content"
                tools:ignore="ContentDescription" />


            <TextView
                android:id="@+id/tv_headline"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="12dp"
                android:ellipsize="end"
                android:maxLines="1"
                android:textSize="13sp"
                android:textColor="@color/white"
                android:textStyle="bold"
                app:layout_constraintStart_toEndOf="@+id/iv_app_icon"
                app:layout_constraintTop_toTopOf="@+id/iv_app_icon"
                tools:text="Test Ad : Google Ads" />

            <TextView
                android:id="@+id/tv_body"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="12dp"
                android:layout_marginEnd="16dp"
                android:ellipsize="end"
                android:maxLines="2"
                android:textColor="@color/white"
                android:paddingVertical="2dp"
                android:textSize="11sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/iv_app_icon"
                app:layout_constraintTop_toBottomOf="@+id/tv_headline"
                tools:text="Stay up to date with your Ads Check how your ads are performing Checkit now" />


            <Button
                android:id="@+id/btn_cta"
                android:layout_width="0dp"
                android:layout_height="45dp"
                android:layout_marginHorizontal="16dp"
                android:layout_marginTop="12dp"
                android:layout_marginBottom="10dp"
                android:background="@drawable/button_bg"
                android:gravity="center"
                android:textColor="@color/white"
                android:textSize="12sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tv_body"
                tools:text="INSTALL" />


        </androidx.constraintlayout.widget.ConstraintLayout>

    </com.google.android.gms.ads.nativead.NativeAdView>

    <com.facebook.shimmer.ShimmerFrameLayout
        android:id="@+id/shimmerFrameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:orientation="vertical">


        <TextView
            android:id="@+id/btn_cta1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginHorizontal="16dp"
            android:layout_marginVertical="20dp"
            android:layout_marginBottom="4dp"
            android:gravity="center"
            android:text="Loading Ad..."
            android:textColor="@color/white"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent" />


    </com.facebook.shimmer.ShimmerFrameLayout>
</FrameLayout>

并创建一个可组合项,它将使用 ViewBinding 并访问布局文件。

@Composable
fun NativeMediumAd() {
    val context = LocalContext.current
    val adUnit: String = "native_ad_id"
    var isAdRequested = false

    AndroidViewBinding(
        factory = LayoutNativeAdMediumBinding::inflate,
        modifier = Modifier
            .navigationBarsPadding()
            .wrapContentHeight(unbounded = true)
    ) {
        if (isAdRequested)
            return@AndroidViewBinding
        val adView = nativeAdView.also { adView ->
            adView.adChoicesView = adChoice
            adView.bodyView = tvBody
            adView.callToActionView = btnCta
            adView.headlineView = tvHeadline
            adView.iconView = ivAppIcon
            adView.mediaView = mvContent
        }
        kotlin.runCatching {
            AdLoader.Builder(adView.context, adUnit)
                .forNativeAd { nativeAd ->
                    nativeAd.body?.let { body ->
                        tvBody.text = body
                    }

                    nativeAd.callToAction?.let { cta ->
                        btnCta.text = cta
                    }

                    nativeAd.headline?.let { headline ->
                        tvHeadline.text = headline
                    }

                    nativeAd.icon?.let { icon ->
                        ivAppIcon.setImageDrawable(icon.drawable)
                    }

                    adView.setNativeAd(nativeAd)
                }
                .withAdListener(object : AdListener() {
                    override fun onAdLoaded() {
                        super.onAdLoaded()

                        shimmerFrameLayout.visibility = View.GONE
                        adView.visibility = View.VISIBLE
                    }

                    override fun onAdFailedToLoad(p0: LoadAdError) {
                        super.onAdFailedToLoad(p0)

                    }
                })
                .withNativeAdOptions(
                    NativeAdOptions.Builder().setAdChoicesPlacement(ADCHOICES_TOP_LEFT).build()
                )
                .build()
        }.onSuccess {
            it.loadAd(AdRequest.Builder().build())
            isAdRequested = true
        }
    }
}

注意:只需在代码中使用

NativeMediumAd()
可组合项即可完成。

快乐创作!!

© www.soinside.com 2019 - 2024. All rights reserved.