feat(character): 캐릭터 탭에 Yandex 인라인 배너를 추가한다

This commit is contained in:
2026-04-27 15:22:11 +09:00
parent d0dd6c9224
commit 8295e3d25e
4 changed files with 309 additions and 0 deletions

View File

@@ -14,9 +14,12 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.Gson
import com.yandex.mobile.ads.banner.BannerAdSize
import com.yandex.mobile.ads.common.AdRequest
import com.zhpan.bannerview.BaseBannerAdapter
import com.zhpan.indicator.enums.IndicatorSlideMode
import com.zhpan.indicator.enums.IndicatorStyle
import kr.co.vividnext.sodalive.BuildConfig
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseFragment
import kr.co.vividnext.sodalive.base.SodaDialog
@@ -37,6 +40,7 @@ import kr.co.vividnext.sodalive.mypage.auth.AuthVerifyRequest
import kr.co.vividnext.sodalive.settings.ContentSettingsActivity
import kr.co.vividnext.sodalive.splash.SplashActivity
import org.koin.android.ext.android.inject
import kotlin.math.roundToInt
// 캐릭터 탭 프래그먼트
@OptIn(UnstableApi::class)
@@ -61,16 +65,43 @@ class CharacterTabFragment : BaseFragment<FragmentCharacterTabBinding>(
viewModel.fetchData()
}
override fun onDestroyView() {
binding.yandexInlineBannerView.destroy()
super.onDestroyView()
}
private fun setupView() {
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
setupBanner()
setupRecentCharactersRecyclerView()
setupCharacterTabInlineBanner()
setupPopularCharactersRecyclerView()
setupNewCharactersRecyclerView()
setupRecommendCharactersRecyclerView()
}
private fun setupCharacterTabInlineBanner() {
binding.yandexInlineBannerView.post {
val density = resources.displayMetrics.density
val adWidthPixels = binding.yandexInlineBannerView.width.takeIf { it > 0 } ?: screenWidth
val adWidthDp = (adWidthPixels / density).roundToInt()
val maxAdHeightDp = 90
binding.yandexInlineBannerView.apply {
setAdUnitId(BuildConfig.YANDEX_INLINE_BANNER_CHARACTER_TAB_AD_UNIT_ID)
setAdSize(
BannerAdSize.inlineSize(
requireContext(),
adWidthDp,
maxAdHeightDp
)
)
loadAd(AdRequest.Builder().build())
}
}
}
private fun setupBanner() {
val layoutParams = binding
.bannerSlider

View File

@@ -0,0 +1,75 @@
package kr.co.vividnext.sodalive.common
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView
import com.yandex.mobile.ads.banner.BannerAdSize
import com.yandex.mobile.ads.banner.BannerAdView
import com.yandex.mobile.ads.common.AdRequest
import kr.co.vividnext.sodalive.extensions.dpToPx
import kotlin.math.roundToInt
class YandexInlineBannerHeaderAdapter(
private val adUnitId: String,
private val screenWidth: Int
) : RecyclerView.Adapter<YandexInlineBannerHeaderAdapter.BannerViewHolder>() {
private var bannerAdView: BannerAdView? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
val horizontalPadding = 24f.dpToPx().toInt()
val verticalPadding = 24f.dpToPx().toInt()
val container = FrameLayout(parent.context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
}
val bannerView = BannerAdView(parent.context).apply {
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
)
}
container.addView(bannerView)
return BannerViewHolder(container, bannerView).apply {
setIsRecyclable(false)
}
}
override fun getItemCount(): Int = 1
override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
bannerAdView = holder.bannerView
holder.bannerView.post {
val density = holder.bannerView.resources.displayMetrics.density
val adWidthPixels = holder.bannerView.width.takeIf { it > 0 }
?: (screenWidth - 48f.dpToPx().toInt())
val adWidthDp = (adWidthPixels / density).roundToInt().coerceAtLeast(1)
val maxAdHeightDp = 90
holder.bannerView.apply {
setAdUnitId(adUnitId)
setAdSize(
BannerAdSize.inlineSize(
context,
adWidthDp,
maxAdHeightDp
)
)
loadAd(AdRequest.Builder().build())
}
}
}
fun destroy() {
bannerAdView?.destroy()
bannerAdView = null
}
class BannerViewHolder(
container: FrameLayout,
val bannerView: BannerAdView
) : RecyclerView.ViewHolder(container)
}

View File

@@ -82,6 +82,14 @@
</LinearLayout>
<com.yandex.mobile.ads.banner.BannerAdView
android:id="@+id/yandex_inline_banner_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginBottom="24dp"
android:maxHeight="90dp" />
<!-- 인기 캐릭터 섹션 -->
<LinearLayout
android:id="@+id/ll_popular_characters"