Jetpack Compose implementation - pubnative/pubnative-hybid-android-sdk GitHub Wiki
In order to use Banners, we propose creating a composable for the adView, like in the following example:
@Composable
fun AdView(bannerViewModel: BannerViewModel?, adSize: AdSize) {
val context = LocalContext.current
bannerViewModel?.createBannerAd(context, adSize)
if (bannerViewModel?.getAdView() != null) {
AndroidView(factory = { bannerViewModel.getAdView()!! })
}
}
Inside the desired screen, the banner should be loaded, passing the intended ZoneId:
bannerViewModel?.loadBannerAd("2")
(IMPORTANT: Please make sure the ZoneId is the intended one for the AdSize of the placement)
Inside the view model, the banner is held in a variable:
private var banner: HyBidAdView? = null
and it is initiated with:
fun createBannerAd(context: Context, adSize: AdSize) { banner = HyBidAdView(context, adSize) }
Then, the view itself is passed using the getAdView() function, as it can be seen in this example:
fun getAdView() : HyBidAdView? { return banner }
The following listeners should be added to the view model:
- HyBidAdView.Listener
- VideoListener (for MRect Video ads)
A working sample can be found at https://github.com/pubnative/hybid-compose
In order to display native ad inside your composable function , It is recommended that you create all your design components individually inside your composable function with load button
- when button is clicked ,Call loadPNAD which is defined inside your view model and pass all data via live data once these data is received via live data example : Inside your view model :
private val _creativeIdState = mutableStateOf("")
val creativeIdState: State<String> = _creativeIdState
private val _titleState = mutableStateOf("")
val titleState: State<String> = _titleState
private val _descriptionState = mutableStateOf("")
val descriptionState: State<String> = _descriptionState
private val _callToActionState = mutableStateOf("")
val callToActionState: State<String> = _callToActionState
private val _bitmapState: MutableState<Bitmap?> = mutableStateOf(null)
val bitmapState: MutableState<Bitmap?> = _bitmapState
private val _bitmapURLState = mutableStateOf("")
val bitmapURLState: State<String> = _bitmapURLState
private val _iconBitmapState: MutableState<Bitmap?> = mutableStateOf(null)
val iconBitmapState: MutableState<Bitmap?> = _iconBitmapState
private val _iconBitmapURLState = mutableStateOf("")
val iconBitmapURLState: State<String> = _iconBitmapURLState
@Composable
fun loadPNAd() {
nativeAdRequest?.setPreLoadMediaAssets(true)
nativeAdRequest?.load("2", this)
}
override fun onRequestSuccess(ad: NativeAd?) {
ad?.apply {
creativeId?.let {
_creativeIdState.value = it
}
description?.let {
_descriptionState.value = it
}
callToActionText?.let {
_callToActionState.value = it
}
if (bannerBitmap != null) {
_bitmapState.value = bannerBitmap
} else {
_bitmapURLState.value = bannerUrl
}
if (iconBitmap != null) {
_iconBitmapState.value = iconBitmap
} else {
_iconBitmapURLState.value = ad.iconUrl
}
}
}
override fun onRequestFail(p0: Throwable?) {
creativeId?.let {
_creativeIdState.value = "fail to load"
}
}
Inside your composable function :
@OptIn(ExperimentalGlideComposeApi::class)
@Composable
private fun AdContent(padding: PaddingValues, nativeViewModel: NativeViewModel?) {
val creativeId = remember { nativeViewModel?.creativeIdState }
val title = remember { nativeViewModel?.titleState }
val description = remember { nativeViewModel?.descriptionState }
val callToAction = remember { nativeViewModel?.callToActionState }
val bitmap = remember { nativeViewModel?.bitmapState }
val bitmapURL = remember { nativeViewModel?.bitmapURLState }
val icon = remember { nativeViewModel?.iconBitmapState }
val iconURL = remember { nativeViewModel?.iconBitmapURLState }
Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(padding),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.padding(0.dp, 55.dp))
RowButton(txtResource = R.string.load, onClick = {
nativeViewModel?.loadPNAd()
})
Spacer(modifier = Modifier.padding(8.dp))
}
Column(
modifier = Modifier
.height(300.dp)
.fillMaxWidth(),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(padding),
horizontalArrangement = Arrangement.Start,
) {
GlideImage(
model = iconURL?.value,
contentDescription = "iconURL",
modifier = Modifier
.padding(padding)
.width(30.dp)
.height(30.dp)
)
title?.value?.let { Text(text = it) }
}
GlideImage(
model = bitmapURL?.value,
contentDescription = "BannerURL",
modifier = Modifier
.padding(padding)
.fillMaxWidth()
.height(100.dp)
)
}
}
}
It is recommended to use Glide instead of Picasso because it has compose support