-
-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Hello,
I would like to ask how to use a custom template with NativeAd.
When I implement NativeAd, I always have to create an expect class like this:
public expect class NativeAdSmallTemplate : NativeAdTemplate
And I must implement all functions defined in your public abstract class NativeAdTemplate().
As a result, every time I create a new template, I have to re-implement many methods, which makes the process quite complex and repetitive, even though some components are reused multiple times across templates.
I have the following suggestion:
@DependsOnGoogleMobileAds
@Composable
public expect fun NativeAd(
loadedAd: NativeAdHandler,
nativeAdTemplate: @Composable NativeAdUiScope.(NativeAdData) -> Unit,
)
public interface NativeAdUiScope {
public val nativeAdData: NativeAdData
@Composable
public fun NativeAdAdvertiser(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdChoices(modifier: Modifier = Modifier)
@Composable
public fun NativeAdMedia(modifier: Modifier = Modifier)
@Composable
public fun NativeAdPrice(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdStarRating(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdStore(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdAttribution(modifier: Modifier = Modifier, text: String = "Ad")
@Composable
public fun NativeAdHeadline(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdIcon(modifier: Modifier = Modifier)
@Composable
public fun NativeAdBody(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
@Composable
public fun NativeAdCallToAction(modifier: Modifier = Modifier, content: @Composable () -> Unit = {})
}
in android side
public class AndroidNativeAdUiScope(
override val nativeAdData: NativeAdData
) : NativeAdUiScope {
@Composable
override fun NativeAdAdvertiser(
modifier: Modifier,
content: @Composable (() -> Unit)
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
AndroidView(
factory = { context ->
ComposeView(context).apply {
id = View.generateViewId()
setContent(content)
nativeAdView.advertiserView = this
}
},
modifier = modifier,
update = { view -> view.setContent(content) },
)
}
@Composable
override fun NativeAdChoices(
modifier: Modifier
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
AndroidView(
factory = {
AdChoicesView(localContext).apply {
minimumWidth = 15
minimumHeight = 15
}
},
update = { view -> nativeAdView.adChoicesView = view },
modifier = modifier,
)
}
@Composable
override fun NativeAdMedia(
modifier: Modifier
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
AndroidView(
factory = { MediaView(localContext) },
update = { view ->
nativeAdView.mediaView = view
},
modifier = modifier,
)
}
@Composable
override fun NativeAdPrice(
modifier: Modifier,
content: @Composable (() -> Unit)
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.priceView = localComposeView
localComposeView.apply { setContent(content) }
},
modifier = modifier,
)
}
@Composable
override fun NativeAdStarRating(
modifier: Modifier,
content: @Composable (() -> Unit)
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.starRatingView = localComposeView
localComposeView.apply { setContent(content) }
},
modifier = modifier,
)
}
@Composable
override fun NativeAdStore(
modifier: Modifier,
content: @Composable (() -> Unit)
) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.storeView = localComposeView
localComposeView.apply { setContent(content) }
},
modifier = modifier,
)
}
@Composable
override fun NativeAdAttribution(
modifier: Modifier,
text: String
) {
Box(
modifier =
modifier
.background(ButtonDefaults.buttonColors().containerColor)
.clip(ButtonDefaults.shape)
) {
Text(color = ButtonDefaults.buttonColors().contentColor, text = text)
}
}
@Composable
override fun NativeAdHeadline(modifier: Modifier, content: @Composable () -> Unit) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.headlineView = localComposeView
localComposeView.apply {
setContent(content)
}
},
modifier = modifier,
)
}
@Composable
override fun NativeAdIcon(modifier: Modifier) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.iconView = localComposeView
localComposeView.apply {
setContent {
nativeAdData.icon?.let { icon ->
icon.drawable?.toBitmap()?.let { bitmap ->
Image(
modifier = Modifier.clip(RoundedCornerShape(8.dp)),
bitmap = bitmap.asImageBitmap(),
contentDescription = "Icon"
)
}
} ?: Box(
modifier = Modifier
.width(80.dp)
.aspectRatio(1f)
.clip(RoundedCornerShape(8.dp))
.background(Color.White)
)
}
}
},
modifier = modifier,
)
}
@Composable
override fun NativeAdBody(modifier: Modifier, content: @Composable () -> Unit) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.bodyView = localComposeView
localComposeView.apply {
setContent(content)
}
},
modifier = modifier,
)
}
@Composable
override fun NativeAdCallToAction(modifier: Modifier, content: @Composable () -> Unit) {
val nativeAdView =
LocalNativeAdView.current ?: throw IllegalStateException("NativeAdView null")
val localContext = LocalContext.current
val localComposeView =
remember { ComposeView(localContext).apply { id = View.generateViewId() } }
AndroidView(
factory = {
nativeAdView.callToActionView = localComposeView
localComposeView.apply {
setContent(content)
}
},
modifier = modifier,
)
}
}
so my implement just re-write in common main (not in platform side)
private fun NativeAdUiScope.NativeAdSmallTemplate(nativeAd: NativeAdData){
Column(
modifier = Modifier
.fillMaxWidth()
.height(95.sdp)
.border(
1.sdp,
MaterialTheme.englishPalette.outline,
RoundedCornerShape(8.sdp)
)
.background(colors.last(), RoundedCornerShape(8.sdp))
.padding(12.sdp)
) {
Row {
NativeAdIcon()
NativeAdHeadline {}
.......
}
}
}
And Use
NativeAd(
loadedAd = nativeAdHandler,
nativeAdTemplate = { nativeAd ->
NativeAdSmallTemplate(nativeAd)
},
)
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request