본문으로 건너뛰기

커스터마이징

전체 테마

Buzzvil SDK에서 제공하는 기본 UI를 사용해 광고 지면이나 CTA의 색상, 아이콘 이미지 등 테마를 변경할 수 있습니다.

주요 색상

Buzzvil SDK에서 제공하는 UI 중 다이얼로그의 버튼 색상, 바텀 시트 UI의 확인 버튼 등 앱에 연동한 모든 지면 내 주요 UI의 색상(Primary color)을 변경할 수 있습니다.

Primary 색상 변경을 위해 아래와 같이 색상 리소스를 추가하세요.

 중요
리소스 이름은 buzzvil_benefit_hub_brand_primary, buzzvil_benefit_hub_brand_primary_light를 그대로 사용해야 합니다.

✏️  참고
primary light 색상은 primary 색상에 투명도 60%를 적용한 값을 권장합니다. 예를 들어, primary 색상값이 #FF0000 이라면 primary light 색상값은 #99FF0000를 사용하세요.

<!-- res/values/colors.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="your_primary_color">#FF0000</color>
<color name="your_primary_light_color">#99FF0000</color>

<color name="buzzvil_benefit_hub_brand_primary">@color/your_primary_color</color>
<color name="buzzvil_benefit_hub_brand_primary_light">@color/your_primary_light_color</color>
</resources>

리워드 아이콘

Buzzvil SDK에서 제공하는 UI 중 CTA 버튼, 팝 버튼, 유저 프로필 입력 배너 등의 아이콘을 변경할 수 있습니다.

다음은 BuzzAdThemerewardIcon를 추가해 리워드 아이콘을 변경하는 예시입니다. 각 속성 값에서 커스터마이징할 수 있는 UI에 대해서는 아래의 표를 참고하세요.

속성 값커스터마이징이 가능한 UI
rewardIcon
  • 모든 지면: CTA 뷰 리워드 아이콘
  • 베네핏허브: 팝 옵트인 버튼 아이콘
participatedIcon
  • 모든 지면: CTA 뷰

✏️  참고
테마를 변경하려면 BuzzvilSdk.initialize()을 호출해 Buzzvil SDK를 초기화하기 전에 BuzzAdTheme.setGloabalTheme()을 호출해야 합니다.

class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 GlobalTheme을 설정합니다.
val buzzAdTheme = BuzzAdTheme()
.rewardIcon(R.drawable.your_reward_icon)
.participatedIcon(R.drawable.your_participated_icon)
BuzzAdTheme.setGlobalTheme(buzzAdTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

CTA 버튼 자체 구현하기

Buzzvil SDK에서 기본으로 제공하는 UI를 사용하지 않고 CTA 버튼을 자체적으로 구현할 수 있습니다. 자체적으로 구현한 CTA 버튼을 베네핏허브와 네이티브에서 사용할 수 있습니다.

CTA 버튼을 직접 구현하려면 다음의 절차를 따르세요.

  1. 뷰 레이아웃(view_customized_cta.xml)을 구현하세요. 다음은 레이아웃 리소스로 뷰 레이아웃을 구현한 예시입니다.

    <!-- view_customized_cta.xml -->

    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark">
    <!-- CTA 버튼의 텍스트 -->
    <TextView
    android:id="@+id/textCta"/>

    <!-- CTA 버튼의 아이콘 이미지 -->
    <ImageView
    android:id="@+id/imageReward"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:src="아이콘 이미지 리소스"/>

    <!-- CTA 버튼의 리워드 텍스트 -->
    <TextView
    android:id="@+id/textReward"/>
    </LinearLayout>
  2. CtaView 클래스를 상속하는 서브클래스인 CustomCtaView를 생성하세요.

  3. CtaView 클래스에서 사용하던 CTA View 레이아웃을 inflate하도록 구현하세요.

  4. 유저의 광고 참여 상태에 따라 호출되는 아래의 오버라이딩 메소드에서 CTA 버튼의 아이콘 이미지, 텍스트, 리워드 값을 구현하세요.

  • renderViewParticipatingState : 유저가 광고에 참여 중인 상태 (예: 액션형 광고의 랜딩 페이지에 진입한 상태)

  • renderViewParticipatedState : 유저가 광고 참여를 완료한 상태

  • renderViewRewardAvailableState : 유저가 아직 광고에 참여하지 않은 상태

  • renderViewRewardNotAvailableState : 유저가 획득할 리워드가 없는 광고

    class CustomCtaView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    CtaView(context, attrs, defStyleAttr) {
    private val rewardImageView: ImageView
    private val rewardTextView: TextView
    private val ctaTextView: TextView

    constructor(context: Context) : this(
    context,
    null
    )

    constructor(context: Context, attrs: AttributeSet?) : this(
    context,
    attrs,
    0
    )

    init {
    inflate(getContext(), R.layout.custom_cta_view, this)
    rewardImageView = findViewById(R.id.imageReward)
    rewardTextView = findViewById(R.id.textReward)
    ctaTextView = findViewById(R.id.textCta)
    }

    private fun setRewardIcon(@DrawableRes iconResId: Int) {
    rewardImageView.setImageResource(iconResId)
    rewardImageView.visibility = View.VISIBLE
    }

    private fun hideRewardIcon() {
    rewardImageView.visibility = View.GONE
    }

    private fun setCtaText(ctaText: String) {
    ctaTextView.text = ctaText
    }

    private fun setRewardText(rewardText: String) {
    rewardTextView.text = rewardText
    }

    override fun renderViewParticipatingState(callToAction: String) {
    setCtaText("참여 확인 중")
    hideRewardIcon()
    setRewardText("")
    }

    override fun renderViewParticipatedState(callToAction: String) {
    setRewardIcon(R.drawable.custom_participated_icon)
    setRewardText("")
    setCtaText("참여 완료")
    }

    override fun renderViewRewardAvailableState(callToAction: String, reward: Int) {
    setRewardIcon(R.drawable.custom_reward_icon)
    setRewardText(String.format(Locale.US, "+%,d", reward))
    setCtaText(callToAction)
    }

    override fun renderViewRewardNotAvailableState(callToAction: String) {
    hideRewardIcon()
    setRewardText("")
    setCtaText(callToAction)
    }
    }
  1. 자체 구현한 CTA 버튼을 베네핏허브, 네이티브에서 사용하세요. 아래 예시와 같이 DefaultCtaView 대신 자체 구현한 CustomCtaView로 대체하여 사용할 수 있습니다.
<com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/native_ad_view">
<com.buzzvil.buzzad.benefit.presentation.media.MediaView
android:id="@+id/mediaView"/>
<TextView
android:id="@+id/textTitle"/>
<TextView
android:id="@+id/textDescription"/>
<ImageView
android:id="@+id/imageIcon"/>
<!-- DefaultCtaView 대신 직접 구현한 CustomCtaView를 사용할 수 있습니다. -->
<com.your.packagename.CustomCtaView
android:id="@+id/customCtaView"/>
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>

네이티브

네이티브 오버레이 UI

버즈빌 대시 어드민을 통해 오버레이 UI를 구성하는 이미지와 텍스트를 커스터마이징할 수 있습니다.

✏️ 참고
오버레이 UI를 커스텀하지 않거나 커스터마이징 토글을 OFF 하면 버즈빌이 제공하는 UI가 적용됩니다.

네이티브 오버레이 UI를 커스터마이징하려면 다음의 절차를 따르세요.

  1. 버즈빌 대시 어드민(https://dashboard.buzzvil.com/)에 접속하세요.
  2. Inventory Manager에서 앱을 검색하고 선택한 후 왼쪽 메뉴 패널에서 Entry Point Contents 메뉴로 이동하세요.
  3. 진입점 유형 드롭다운 목록에서 ‘네이티브 오버레이’를 선택하세요.
  4. 오버레이 유형별로 커스터마이징 토글을 켜세요.
  5. 원하는 이미지와 UI 스트링을 등록하세요.
    • 커스터마이징 UI를 실시간으로 미리보기할 수 있습니다.
    • 오버레이 UI를 커스텀하지 않으면 버즈빌이 제공하는 UI가 적용됩니다.
    • 이미지와 UI 스트링이 지원하는 규격은 다음과 같습니다.
      • 이미지 포맷: PNG, JPG, JSON(Lottie)
      • 파일 크기: 최대 2 MB
      • 이미지 비율: 312 x 212 (가로 x 세로)
      • UI 스트링 글자 수 & 줄 수: 최대 20 자 (공백 포함) & 두 줄
  6. 오른쪽 상단의 저장하기 버튼을 클릭하세요.

✏️ 참고
SDK Configuration 에서 비활성화한 기능의 오버레이는 접힌 상태로 표시됩니다.

네이티브 오버레이 영역

네이티브 오버레이가 표시되는 영역을 변경하려면 다음과 같이 NativeAd2ViewBindernativeOverlayViewLayout()를 사용하여 네이티브 오버레이가 보여질 영역을 설정합니다.

✏️  참고

  • yourCustomNativeAdLayoutNativeAd2View의 하위 컴포넌트로 구현된 ViewGroup이어야 합니다. e.g. CardView, ConstraintLayout
  • nativeOverlayViewLayout()를 설정하지 않으면 모서리의 radius 값이 12dp인 기본 배경이 적용됩니다.
nativeAd2ViewBinder = NativeAd2ViewBinder.Builder()
.nativeAd2View(nativeAd2View)
...
.nativeOverlayViewLayout(yourCustomNativeAdLayout)
.build(Constant.YOUR_NATIVE_ID)

베네핏허브

Buzzvil SDK에서 제공하는 UI의 디자인을 변경하기 위한 방법을 안내합니다.

내비게이션 바

베네핏허브 내비게이션 바의 UI 스트링을 수정하거나 내비게이션 바 영역을 자체 구현할 수 있습니다.

내비게이션 바 UI 스트링 변경하기

내비게이션 바의 UI 스트링을 변경할 수 있습니다.

<!-- res/values/strings.xml -->
<resources>
<string name="your_custom_title">커스텀 타이틀</string>
</resources>
val buzzAdFeedTheme = BuzzAdFeedTheme.getDefault()
.navigationBarTitle(R.string.your_custom_title)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

내비게이션 바 자체 구현하기

프래그먼트로 베네핏허브 연동하기 항목을 참고하여 내비게이션 바를 자체 구현할 수 있습니다.

유저 프로필 입력 배너

유저 프로픽 입력 배너의 아이콘을 변경할 수 있습니다.

class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.profileBannerIcon(R.drawable.your_profile_banner_icon)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

헤더

베네핏허브 상단의 헤더를 원하는 목적에 맞게 자유롭게 활용할 수 있습니다. 예를 들어, 베네핏허브 영역을 설명하는 공간으로 활용하거나 적립 가능한 금액을 표시할 수도 있습니다.

✏️ 참고
헤더 영역을 자체 구현하지 않으면 총 적립 가능 금액을 보여주는 기본 헤더가 표시됩니다.
헤더 영역을 사용하지 않으려면 버즈빌 담당자(help@buzzvil.com)에게 연락하세요.

다음은 헤더 영역을 변경하는 예시입니다.

FeedHeaderViewAdapter 인터페이스를 구현하는 클래스를 생성하고 Custom View(your_feed_header_layout)를 헤더 영역에 구현합니다. 그리고 FeedConfigfeedHeaderViewAdapterClass() 속성에 새로 구현한 클래스를 추가합니다.

class CustomFeedHeaderViewAdapter: FeedHeaderViewAdapter {

override fun onCreateView(context: Context, parent: ViewGroup): View {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
return inflater.inflate(R.layout.feed_header_layout, parent, false)
}

override fun onBindView(view: View, reward: Int) {
val rewardTextView: TextView = view.findViewById(R.id.textReward)
rewardTextView.text = reward.toString()
}

override fun onDestroyView() {
// Use this callback for clearing memory
}
}
val feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapteri::class.java)
.build();

광고 분류 필터

광고 분류 필터의 기본 색상은 monochrome이며, primary color를 따라가도록 변경할 수 있습니다.

class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 GlobalTheme을 설정합니다.
val buzzAdTheme = BuzzAdTheme()
.usePrimaryColorInFilter(true) // true: primary color, false: monocrhome
BuzzAdTheme.setGlobalTheme(buzzAdTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

광고 디자인

Buzzvil SDK에서 제공하는 광고는 일반 광고와 쇼핑 광고가 있습니다.

  • 일반 광고: 쇼핑 광고를 제외한 나머지 유형의 광고입니다.
  • 쇼핑 광고: 유저가 광고를 통해 물건 구매를 달성하는 경우 유저에게 구매 금액의 일정 비율을 포인트로 돌려주는 광고입니다.

두 유형 모두 광고를 표현할 수 있는 다양한 정보로 구성됩니다. 일반 광고와 쇼핑 광고를 구성하는 요소와 UI에 대해서는 아래의 표를 참고하세요.

구성 요소일반쇼핑설명
광고 소재필수필수
  • 이미지, 동영상 등 광고 소재입니다. 광고 소재의 종횡비는 반드시 유지해야 합니다.
  • com.buzzvil.buzzad.benefit.presentation.media.MediaView를 사용해서 표시해야 합니다.
  • 사이즈: 1,200 x 627 (px)
  • 여백을 추가할 수 있습니다. 자세한 내용은 버즈빌 담당자에게 문의하세요.
광고 제목필수선택광고의 제목입니다. 최대 10자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
광고 설명필수선택광고에 대한 상세 설명입니다. 최대 40자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
광고주 아이콘필수선택
  • 광고주 아이콘 이미지입니다. 반드시 아이콘의 종횡비를 유지해야 합니다.
  • 사이즈: 80 x 80 (px)
CTA 버튼필수필수
  • 광고의 참여를 유도하는 버튼입니다. 최대 7자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다.
  • com.buzzvil.buzzad.benefit.presentation.media.DefaultCtaView를 사용해서 표시해야 합니다.

  • ✏️  참고
    CTA 버튼의 디자인을 변경하려면 CTA 버튼 자체 구현하기 토픽을 참고하세요.
광고 알림 문구권장권장광고임을 명시하는 문구입니다. (예: 광고, ad, 스폰서, Sponsored)
OriginalPrice View-권장상품의 원가를 표시합니다.
Price View-필수상품의 할인된 가격을 표시합니다.
DiscountRate View-권장상품 가격의 할인율을 표시합니다. 할인율은 원가와 할인가로 비교하여 산출해서 표시해야 합니다.

광고 디자인 자체 구현하기

광고의 디자인을 변경하려면 다음의 절차를 따르세요.

❗️ 주의
NativeAdView는 광고 디자인 자체 구현에서만 사용해야 합니다. 네이티브 구현은 NativeAd2View를 사용하세요. 자세한 내용은 네이티브를 참고하세요.

  1. 광고용 NativeAdView의 규격에 맞는 레이아웃(your_benefit_hub_ad.xml)을 구현하세요.

    <!-- your_benefit_hub_ad.xml -->

    <com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView
    android:id="@+id/nativeAdView" ...>

    <!-- MediaView와 DefaultCtaView는 NativeAdView의 하위 컴포넌트로 구현해야 합니다. -->
    <!-- 참고: NativeAdView는 FrameLayout 입니다. -->
    <LinearLayout ... >

    <!-- MediaView는 일반 광고와 쇼핑 광고에서 모두 사용됩니다. -->
    <com.buzzvil.buzzad.benefit.presentation.media.MediaView
    android:id="@+id/mediaView" ... />

    <!-- 일반 광고에서 사용되는 뷰 레이아웃입니다. -->
    <LinearLayout android:id="@+id/excpsLayout" ... >
    <androidx.appcompat.widget.AppCompatImageView android:id="@+id/adIconImage" ... />

    <TextView android:id="@+id/adTitleText" ... />

    <TextView android:id="@+id/adDescriptionText" ... />
    </LinearLayout>

    <!-- 쇼핑 광고에서 사용되는 뷰 레이아웃입니다. -->
    <LinearLayout android:id="@+id/cpsLayout" ...>
    <TextView android:id="@+id/discountPercentageText" ... />

    <TextView android:id="@+id/priceText" ... />

    <TextView android:id="@+id/originalPriceText" ... />
    </LinearLayout>

    <!-- DefaultCtaView 대신 직접 구현한 CustomCtaView를 사용할 수 있습니다. -->
    <com.buzzvil.buzzad.benefit.presentation.media.DefaultCtaView
    android:id="@+id/ctaView" ... />

    </LinearLayout>

    </com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>
  2. BenefitHubAdViewAdapter의 상속 클래스를 구현하세요.

    • onCreateView()에서 your_benefit_hub_ad.xml을 사용하여 뷰를 생성하세요.
    • onBindView()에서 NativeAdViewBinder를 이용하여 광고 데이터(NativeAd)를 앞서 생성한 NativeAdView에 바인딩하세요.
      • onBindView()NativeAdView를 반환해야 합니다.
    • onDestroyView()에서 리스너 및 뷰를 해제하세요.
    • NativeAdEventListener를 통해 광고 콜백 이벤트 수신 기능을 부가적으로 추가할 수도 있습니다.
    class CustomBenefitHubAdViewAdapter : BenefitHubAdViewAdapter {
    private lateinit var binding: YourBenefitHubAdBinding
    private var nativeAd: NativeAd? = null
    private var nativeAdViewBinder: NativeAdViewBinder? = null

    // 리스너 구현은 선택 사항입니다.
    private val listener = object : NativeAdEventListener {
    override fun onImpressed(nativeAd: NativeAd) {}
    override fun onClicked(nativeAd: NativeAd) {}
    override fun onRewardRequested(nativeAd: NativeAd) {}
    override fun onRewarded(nativeAd: NativeAd, nativeAdRewardResult: RewardResult?) {}
    override fun onParticipated(nativeAd: NativeAd) {}
    }

    override fun onCreateView(context: Context, parent: ViewGroup): View {
    val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    binding = YourBenefitHubAdBinding.inflate(inflater, parent, false)
    return binding.root
    }

    override fun getNativeAdView(): NativeAdView {
    return binding.nativeAdView
    }

    override fun onBindView(nativeAd: NativeAd) {
    val builder = NativeAdViewBinder.Builder(binding.root, binding.adMediaView)
    .ctaView(binding.adCtaView)
    .iconImageView(binding.adIconImage)
    .titleTextView(binding.adTitleText)
    .descriptionTextView(binding.adDescriptionText)
    .addClickableView(binding.yourClickableArea) // (Optional) 클릭 가능한 영역을 추가합니다.

    if (nativeAd.shoppingProduct == null) {
    // 일반 광고 (CPS 외)
    binding.excpsLayout.visibility = View.VISIBLE
    binding.cpsLayout.visibility = View.GONE
    } else {
    // 쇼핑 광고 (CPS)
    binding.excpsLayout.visibility = View.GONE
    binding.cpsLayout.visibility = View.VISIBLE

    setCpsView(nativeAd.shoppingProduct!!)
    }

    val nativeAdViewBinder = builder.build()
    nativeAdViewBinder.bind(nativeAd)

    nativeAd.addNativeAdEventListener(listener)

    this.nativeAd = nativeAd
    this.nativeAdViewBinder = nativeAdViewBinder
    }

    override fun onDestroyView() {
    nativeAd?.removeNativeAdEventListener(listener)
    nativeAdViewBinder?.unbind()

    nativeAd = null
    nativeAdViewBinder = null
    }

    private fun setCpsView(product: Product) {
    val discountedPrice = product.discountedPrice
    if (discountedPrice != null) {
    // 할인이 있는 쇼핑 광고
    binding.originalPriceText.paintFlags = binding.originalPriceText.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
    var percentage = 0
    if (product.price > discountedPrice) {
    percentage = ((product.price - discountedPrice) / product.price * 100).roundToInt()
    }
    if (percentage > 0) {
    binding.priceText.text = getCommaSeparatedPrice(discountedPrice.toLong())
    binding.originalPriceText.text = getCommaSeparatedPrice(product.price.toLong())
    binding.discountPercentageText.text = String.format(Locale.ROOT, "%d%%", percentage)
    binding.discountPercentageText.visibility = View.VISIBLE
    } else {
    binding.priceText.text = getCommaSeparatedPrice(product.price.toLong())
    binding.originalPriceText.text = ""
    binding.discountPercentageText.visibility = View.GONE
    }
    } else {
    // 할인이 없는 쇼핑 광고
    binding.priceText.text = getCommaSeparatedPrice(product.price.toLong())
    binding.originalPriceText.text = ""
    binding.discountPercentageText.visibility = View.GONE
    }
    }

    private fun getCommaSeparatedPrice(price: Long): String {
    val contextForResource = binding.root.context
    return String.format(
    Locale.getDefault(),
    contextForResource.getString(R.string.custom_cps_price_unit),
    price
    )
    }
    }
    <!-- res/values/strings.xml -->
    <resources>
    <string name="custom_cps_price_unit">%,d원</string>
    </resources>
  3. FeedConfig에 위에서 작성한 CustomBenefitHubAdViewAdapter를 광고 어댑터 클래스로 설정하세요.

    val feedConfig = FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    .benefitHubAdViewAdapterClass(CustomBenefitHubAdViewAdapter::class.java)
    .build()

광고 미할당 안내 UI

광고 미할당 시 이탈을 막기 위해 유저는 3번까지 재시도하는 UX로 설계되어 있습니다. 광고 미할당 안내 UI에서는 각 재시도 회차별 UI 스트링과 이미지를 변경할 수 있습니다.

재시도 회차제목내용버튼
0회차미션을 준비 중이에요다시 미션을 불러와서 포인트를 모아보시겠어요?미션 불러오기
1회차미션을 준비 중이에요미션을 로딩 중이에요. 잠시 후 다시 시도해주세요.다시 불러오기
2회차미션을 준비 중이에요미션 준비에 시간이 걸리고 있습니다. 잠시 후 다시 시도해주세요.한번 더 불러오기
3회차(마지막)미션을 준비 중이에요전체 필터: 지금은 참여 가능한 미션이 없습니다. 잠시 후 다시 방문해주세요.
그 외 필터: 지금은 참여 가능한 미션이 없습니다. 다른 미션에 참여해서 포인트를 모아보세요!
전체 필터: 나중에 다시 올게요
그 외 필터: 다른 미션 참여하기
<!-- res/values/strings.xml -->
<string name="your_no_fill_error_title">미션을 준비 중이에요</string>

<string name="your_no_fill_error_description_1st">다시 미션을 불러와서 포인트를 모아보시겠어요?</string>
<string name="your_no_fill_error_description_2nd">미션을 로딩 중이에요. 잠시 후 다시 시도해주세요.</string>
<string name="your_no_fill_error_description_3rd">미션 준비에 시간이 걸리고 있습니다. 잠시 후 다시 시도해주세요.</string>
<string name="your_no_fill_error_description_final_all_filter">지금은 참여 가능한 미션이 없습니다. 잠시 후 다시 방문해주세요.</string>
<string name="your_no_fill_error_description_final_other_filters">다른 미션 참여하기</string>

<string name="your_no_fill_error_button_1st">미션 불러오기</string>
<string name="your_no_fill_error_button_2nd">다시 불러오기</string>
<string name="your_no_fill_error_button_3rd">한번 더 불러오기</string>
<string name="your_no_fill_error_button_final_all_filter">나중에 다시 올게요</string>
<string name="your_no_fill_error_button_final_other_filters">지금은 참여 가능한 미션이 없습니다. 다른 미션에 참여해서 포인트를 모아보세요!</string>
class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.noFillErrorImage(R.drawable.your_no_fill_error_image)
.noFillErrorTitle(R.string.your_no_fill_error_title)
.noFillErrorDescription1st(R.string.your_no_fill_error_description_1st)
.noFillErrorDescription2nd(R.string.your_no_fill_error_description_2nd)
.noFillErrorDescription3rd(R.string.your_no_fill_error_description_3rd)
.noFillErrorDescriptionFinalAllFilter(R.string.your_no_fill_error_description_final_all_filter)
.noFillErrorDescriptionFinalOtherFilters(R.string.your_no_fill_error_description_final_other_filters)
.noFillErrorButton1st(R.string.your_no_fill_error_button_1st)
.noFillErrorButton2nd(R.string.your_no_fill_error_button_2nd)
.noFillErrorButton3rd(R.string.your_no_fill_error_button_3rd)
.noFillErrorButtonFinalAllFilter(R.string.your_no_fill_error_button_final_all_filter)
.noFillErrorButtonFinalOtherFilters(R.string.your_no_fill_error_button_final_other_filters)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

유저 프로필 오류 안내 UI

유저 프로필이 설정되지 않았을 때 유저에게 노출되는 화면의 UI 스트링과 이미지를 변경할 수 있습니다.

<!-- res/values/strings.xml -->
<string name="your_user_profile_error_title">미션을 준비 중이에요</string>
<string name="your_user_profile_error_description">잠시 후 다시 시도해주세요.</string>
class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.userProfileErrorImage(R.drawable.your_user_profile_error_image)
.userProfileErrorTitle(R.string.your_user_profile_error_title)
.userProfileErrorDescription(R.string.your_user_profile_error_description)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

서버 오류 안내 UI

서버가 유저에게 노출되는 화면의 UI 스트링과 이미지를 변경할 수 있습니다.

<!-- res/values/strings.xml -->
<string name="your_server_error_title">미션을 준비 중이에요</string>
<string name="your_server_error_description">잠시 후 다시 시도해주세요.</string>
class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.serverErrorImage(R.drawable.your_server_error_image)
.serverErrorTitle(R.string.your_user_profile_error_title)
.serverErrorDescription(R.string.your_server_error_description)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

기타 오류 화면 UI

기타 오류 화면별 이미지를 변경할 수 있습니다.

속성설명
privacyPolicyErrorIcon개인정보 제3자 제공 동의를 받아야 하는 경우 노출되는 이미지를 변경합니다.
agePolicyErrorIcon네트워크 에러 발생 시 노출되는 이미지를 변경합니다.
networkErrorIcon네트워크 에러 발생 시 노출되는 이미지를 변경합니다.
unknownErrorIcon알 수 없는 오류 발생 시 노출되는 이미지를 변경합니다.
class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.privacyPolicyErrorImage(R.drawable.your_privacy_policy_error_image)
.agePolicyErrorImage(R.drawable.your_age_policy_error_image)
.networkErrorImage(R.drawable.your_nework_error_image)
.unknownErrorImage(R.drawable.your_unknown_error_image)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

팝 추가 유도 모달

팝을 연동한 경우 유저에게 팝 버튼 활성화를 유도하는 모달의 이미지를 변경할 수 있습니다.

class App : Application() {
override fun onCreate() {
super.onCreate()

val buzzAdBenefitConfig = ...

// BuzzvilSdk.initialize()를 호출하기 전에 FeedTheme을 설정합니다.
val buzzAdFeedTheme = BuzzAdFeedTheme()
.popModalImage(R.drawable.your_pop_modal_image)
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme)

// Buzzvil SDK 초기화
BuzzvilSdk.initialize(...)
}
}

개인정보 제3자 제공 동의 UI 자체 구현

개인정보 제3자 제공 동의 UI를 자체 구현하는 경우, SDK에 동의 여부를 전달해야 합니다. 아래 표를 참고하여 적절한 함수를 호출 해 주세요.

ClassAPI설명
BuzzAdBenefitgetPrivacyPolicyManager() (정적 메소드)PrivacyPolicyManager 인스턴스를 반환합니다.
PrivacyPolicyManagergrantConsent()개인 정보 수집에 동의합니다. 사용자가 처음 피드 지면에 진입하기 전에 호출하면 사용자에게 개인정보 제3자 제공 동의 UI가 보이지 않습니다.
revokeConsent()개인 정보 수집 동의를 철회합니다. 사용자가 동의를 철회하고 피드 지면에 진입하는 경우, 개인정보 제3자 제공 동의 UI가 다시 표시됩니다.
isConsentGranted()개인 정보 수집 동의 여부를 확인합니다.

사용 예시

val privacyPolicyManager = BuzzAdBenefit.getPrivacyPolicyManager()

// 직접 구현한 개인정보 제3자 제공 동의 UI에서 동의를 받았을 경우 아래 코드를 실행하면, 피드 화면에서 개인정보 제3자 제공 동의 UI가 노출되지 않으면서 광고 할당이 정상적으로 진행 됩니다.
// 아래의 코드를 실행하지 않을 경우 피드 진입 시 개인정보 제3자 제공 동의 UI가 노출되기 때문에 필수적으로 실행이 필요합니다.
privacyPolicyManager.grantConsent()

// 아래 코드를 통해서 수집 동의를 철회할 수 있습니다. 이 코드가 실행되면 피드에서 광고 할당이 이루어지지 않습니다.
privacyPolicyManager.revokeConsent()

인터스티셜

주요 UI의 색상(Primary color)을 변경할 수 있는 GlobalTheme을 사용해 진입 경로 레이아웃의 베네핏허브 진입 유도 문구 색상, CTA 버튼 배경 색상과 리워드 아이콘이 함께 변경됩니다. 자세한 내용은 전체 테마 토픽을 참고하세요.