我正在尝试从 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 编写广告代码,或者我该如何解决这个问题?
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()
可组合项即可完成。
快乐创作!!