...
광고 분류 기능에 대한 설정은 앱에서 코드를 수정하거나 재배포 하지 재배포하지 않고 변경할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.
...
탭으로 분류할 수 있는 광고의 유형은 노출형 광고, 참여형 광고, 비디오 광고, 소셜미디어 광고, 쇼핑 광고입니다. 각 탭은 한 개 이상의 광고 유형으로 구성할 수 있습니다. 단, 쇼핑 광고의 경우 다른 광고 유형과 함께 탭으로 구성할 수 없습니다.
탭이 여러 개의 광고 유형으로 구성되면 ‘클릭하기’, ‘참여하기’ 등 광고 유형을 세분화하는 필터 UI가 노출됩니다.
...
Feed 무한 스크롤 기능은 사용자가 Feed에 진입해 할당된 광고 목록을 끝까지 스크롤 해 더 이상 볼 수 있는 광고가 없으면 자동으로 추가 광고를 할당해 기능입니다. 이 기능은 기본적으로 활성화 되어 활성화되어 있으며, 앱에서 코드를 수정하거나 재배포를 하지 않고 무한 스크롤 기능의 활성화 여부를 설정할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.
...
Code Block | ||
---|---|---|
| ||
final BuzzAdFeedTheme buzzAdFeedTheme = BuzzAdFeedTheme.getDefault() .toolbarHeight(R.dimen.YOUR_TOOL_BAR_HEIGHT); BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme); |
헤더 영역 자체 구현하기
...
Feed 헤더 영역을 자유롭게 활용할 수 있습니다. 예를 들어, Feed 영역을 설명하는 공간으로 활용하거나 적립 가능한 금액을 표시할 수도 있습니다.
...
다음은 헤더 영역을 변경하는 예시입니다.
FeedHeaderViewAdapter
인터페이스를 구현하는 클래스를 생성하고 Custom View(your_feed_header_layout
)를 헤더 영역에 구현합니다. 그리고 FeedConfig
의 feedHeaderViewAdapterClass()
속성에 새로 구현한 클래스를 추가합니다.
Code Block | ||
---|---|---|
| ||
public class CustomFeedHeaderViewAdapter implements FeedHeaderViewAdapter { @Override public View onCreateView(final Context context, final ViewGroup parent) { final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); return inflater.inflate(R.layout.your_feed_header_layout, parent, false); } @Override public void onBindView(final View view, final int reward) { // Display total reward on the header if needed. valfinal TextView textView: TextView = view.findViewById(R.id.your_textview); textView.text = setText(String.format("리워드 %d원", reward)); } @Override public void onDestroyView() { // Use this this callback for clearing memory } } |
...
BaseRewardNotificationAdapter
인터페이스를 구현하는 클래스를 생성하세요.Code Block language java public class CustomBaseRewardNotificationAdapter implements BaseRewardNotificationAdapter { @NonNull @Override public View onCreateView(@NonNull Context context, @NonNull ViewGroup viewGroup) { return LayoutInflater.from(context).inflate(R.layout.YOUR_LAYOUT, viewGroup, false); } @Override public void onBindView(@NonNull View view, int reward) { TextView textView = view.findViewById(R.id.YOUR_TEXT_ID); textView.setText(reward + " 포인트가 적립되었습니다."); } }
FeedConfig
에서 이전 단계에서 생성한CustomBaseRewardNotificationAdapter
를FeedConfig
에 설정하세요.Code Block language java final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID") .baseRewardNotificationAdapterClass(CustomBaseRewardNotificationAdapter.class) .build();
...
광고 유형 | 항목 | 설명 | |||||||
---|---|---|---|---|---|---|---|---|---|
공통(일반, 쇼핑 적립) |
| 광고의 제목입니다. 최대 10자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호도 대체할 수 있습니다. | |||||||
| 이미지, 동영상 등 광고 소재입니다. 광고 소재의 종횡비는 반드시 유지해야 합니다.
| ||||||||
| 광고에 대한 상세 설명입니다. 최대 40자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호도 대체할 수 있습니다. | ||||||||
| 광고주 아이콘 이미지입니다. 아이콘의 종횡비는 반드시 유지해야 합니다.
| ||||||||
| 광고의 참여를 유도하는 버튼입니다. 최대 7자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호도 대체할 수 있습니다.
| ||||||||
| 광고임을 명시하는 문구입니다. | ||||||||
쇼핑 적립 |
| 상품의 원가를 표시합니다. | |||||||
| 상품의 할인된 가격을 표시합니다. | ||||||||
| 상품 가격의 할인율을 표시합니다. 할인율은 원가와 할인가로 비교하여 산출해서 표시해야 합니다. |
...
쇼핑 적립 광고용
NativeAdView
의 규격에 맞는 레이아웃(your_feed_ad_cps.xml
)을 구현하세요.일반 광고용 레이아웃에서
priceText
,originalPriceText
,discountPercentageText
를 추가해야 합니다.Code Block language xml <!-- your_feed_ad_cps.xml --> <?xml version="1.0" encoding="utf-8"?> <com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView android:id="@+id/native_ad_view"> <LinearLayout> <!-- MediaView와 DefaultCtaView는 NativeAdView의 하위 컴포넌트로 구현합니다. --> <com.buzzvil.buzzad.benefit.presentation.media.MediaView android:id="@+id/mediaView" ...생략... /> <TextView android:id="@+id/priceText" ...생략... /> <TextView android:id="@+id/originalPriceText" ...생략... /> <TextView android:id="@+id/discountPercentageText" ...생략... /> </LinearLayout> </com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>
일반 광고 디자인 자체 구현하기 토픽을 참고해
AdsAdapter
의 상속 클래스를 구현하세요.
다음의 예시 코드를 참고하세요.Code Block language java public class CustomCPSAdsAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> { @NonNull @Override public NativeAdViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); final NativeAdView feedNativeAdView = (NativeAdView) inflater.inflate(R.layout.your_feed_ad_cps, parent, false); return new NativeAdViewHolder(feedNativeAdView); } @Override public void onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) { super.onBindViewHolder(holder, nativeAd); final NativeAdView view = (NativeAdView) holder.itemView; // 광고 레이아웃 컴포넌트를 생성합니다. ...생략... final TextView priceText = view.findViewById(R.id.discountedPriceText); final TextView originalPriceText = view.findViewById(R.id.originalPriceText); final TextView discountPercentageText = view.findViewById(R.id.discountPercentageText); // 광고 데이터(NativeAd)를 바인딩합니다. ...생략... final Product product = nativeAd.getShoppingProduct(); if (product != null) { if (product.getDiscountedPrice() != null) { // 할인이 있는 쇼핑 광고 originalPriceText.setPaintFlags(originalPriceText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); int percentage = 0; if (product.getPrice() > product.getDiscountedPrice()) { percentage = Math.round(((product.getPrice() - product.getDiscountedPrice()) / product.getPrice() * 100)); } if (percentage > 0) { priceText.setText(getCommaSeparatedPrice(product.getDiscountedPrice().longValue())); originalPriceText.setText(getCommaSeparatedPrice((long) product.getPrice())); discountPercentageText.setText(String.format(Locale.ROOT, "%d%%", percentage)); discountPercentageText.setVisibility(View.VISIBLE); } else { priceText.setText(getCommaSeparatedPrice((long) product.getPrice())); originalPriceText.setText(""); discountPercentageText.setVisibility(View.GONE); } } else { // 할인이 없는 쇼핑 광고 priceText.setText(getCommaSeparatedPrice((long) product.getPrice())); originalPriceText.setText(""); discountPercentageText.setVisibility(View.GONE); } } final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(view, mediaView) .descriptionTextView(descriptionView) .ctaView(ctaView) // 부가 기능: 텍스트를 클릭할 수 있도록 설정합니다. .addClickableView(discountPercentageText) .addClickableView(priceText) .addClickableView(originalPriceText) .build() viewBinder.bind(nativeAd) ...생략... } private String getCommaSeparatedPrice (long price){ return String.format(Locale.getDefault(), "₩%,d", price); } }
FeedConfig
에 위에서 작성한CustomCPSAdsAdapter
를 쇼핑 적립형 광고 어댑터 클래스로 설정하세요.Code Block language java final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID") .cpsAdsAdapterClass(YourCPSAdsAdapter.class) .build();
...
뷰 레이아웃(
view_customized_cta.xml
)을 구현하세요.
다음은 레이아웃 리소스로 뷰 레이아웃을 구현한 예시입니다.Code Block language 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>
CtaView
클래스를 상속하는 서브클래스인CustomCtaView
를 생성하세요.CtaView
클래스에서 사용하던 CTA View 레이아웃을inflate
하도록 구현하세요.사용자의 광고 참여 상태에 따라 호출되는 아래의 오버라이딩 메소드에서 CTA 버튼의 아이콘 이미지, 텍스트, 리워드 값을 구현하세요.
renderViewParticipatingState
: 사용자가 광고에 참여 중인 상태 (예: 액션형 광고의 랜딩 페이지에 진입한 상태)renderViewParticipatedState
: 사용자가 광고 참여를 완료한 상태renderViewRewardAvailableState
: 사용자가 아직 광고에 참여하지 않은 상태renderViewRewardNotAvailableState
: 사용자가 획득할 리워드가 없는 광고Code Block language java public class CustomCtaView extends CtaView { private final ImageView rewardImageView; private final TextView rewardTextView; private final TextView ctaTextView; public CustomCtaView(@NonNull Context context) { this(context, null); } public CustomCtaView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CustomCtaView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO: 기존에 사용하던 CTA View 레이아웃을 inflate 하도록 구현하세요. inflate(getContext(), R.layout.view_customized_cta, this); this.rewardImageView = findViewById(R.id.imageReward); this.rewardTextView = findViewById(R.id.textReward); this.ctaTextView = findViewById(R.id.textCta); } // CTA 텍스트 설정 public void setCtaText(String ctaText) { ctaTextView.setText(ctaText); } // CTA 리워드 값 설정 public void setRewardText(String rewardText) { rewardTextView.setText(rewardText); } // CTA 아이콘 설정 public void setRewardIcon(@DrawableRes int iconResId) { rewardImageView.setImageResource(iconResId); rewardImageView.setVisibility(View.VISIBLE); } // CTA 아이콘 숨기기 처리 public void hideRewardIcon() { rewardImageView.setVisibility(View.GONE); } // 사용자가 광고에 참여 중인 상태 @Override public void renderViewParticipatingState(@NonNull String callToAction) { setCtaText("참여 확인 중"); hideRewardIcon(); setRewardText(""); } // 사용자가 광고 참여를 완료한 상태 @Override public void renderViewParticipatedState(@NonNull String callToAction) { setRewardIcon(R.drawable.my_participated_icon); setRewardText(""); setCtaText("참여 완료"); } // 사용자가 아직 광고에 참여하지 않은 상태 @Override public void renderViewRewardAvailableState(@NonNull String callToAction, int reward) { setRewardIcon(R.drawable.my_reward_icon); setRewardText(String.format(Locale.US, "+%,d", reward)); setCtaText(callToAction); } // 사용자가 획득할 리워드가 없는 광고 @Override public void renderViewRewardNotAvailableState(@NonNull String callToAction) { hideRewardIcon(); setRewardText(""); setCtaText(callToAction); } }
새로 생성한
CustomCtaView
클래스의 경로를 Feed 광고 레이아웃에 설정하세요.
다음은 Feed 광고의 레이아웃 예시입니다.Code Block language xml <com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView 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"/> <!-- TODO: 새로 생성한 CustomCtaView 클래스 경로를 설정합니다. --> <com.your.packagename.CustomCtaView android:id="@+id/customCtaView"/> </com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>
다음 순서에 따라 직접 구현한 CTA 버튼을 Feed 광고에 반영하세요.
Feed 광고 레이아웃에서
NativeAdView
와 커스텀 CTA 버튼인CustomCtaView
를 가져오세요.loadAd()
메소드를 호출한 후 Feed 광고가 성공적으로 할당되어onAdLoaded
콜백 메소드가 호출되면,NativeAdViewBinder
의ctaView
속성을customCtaView
로 설정하세요.bind()
를 호출하여 광고 레이아웃에 광고 데이터를 광고 디자인 자체 구현하기를 참고하여CustomAdsAdapter
를 구현하세요.CustomAdsAdapter.onBindViewHolder
에서CustomCtaView
를 객체화하세요.NativeAdViewBinder.Builder
에 새로 생성한CustomCtaView
를 바인딩하세요.Code Block language java //class TODOCustomAdAdapter: Feed 광고 레이아웃에서 NatieAdView와 구성 요소를 가져옵니다.AdsAdapter<AdsAdapter.NativeAdViewHolder>() { // 생략... final NativeAdView nativeAdView = findViewById(R.id.your_native_ad_view); //... 생략 ... // TODO: Feed 광고 레이아웃에서 CustomCtaView를 가져옵니다. final CustomCtaView customCtaView = nativeAdView.findViewById(R.id.customCtaView); final NativeAdRequest nativeAdRequest = new NativeAdRequest.Builder().build(); final BuzzAdNative buzzAdNative = new BuzzAdNative("YOUR_NATIVE_UNIT_ID"); buzzAdNative.loadAd(nativeAdRequest, new BuzzAdNative.AdLoadListener() { @Override public void onAdLoaded(@NotNull NativeAd nativeAd) { // 할당된 광고가 있으면 호출됩니다. // TODO: 광고 데이터를 바인딩할 때, ctaView 속성을 customCtaView로 설정합니다. final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(nativeAdView, mediaView) .titleTextView(titleTextView) override fun onBindViewHolder(holder: NativeAdViewHolder, nativeAd: NativeAd) { super.onBindViewHolder(holder, nativeAd) // 생략... val customCtaView: CustomCtaView = view.findViewById(R.id.customCtaView) val viewBinder: NativeAdViewBinder = NativeAdViewBinder.Builder(view, mediaView) // 생략... .ctaView(customCtaView) .build() viewBinder.bind(nativeAd) } }
Info |
---|
SDK에서 제공하는 |
광고 미할당 안내 디자인 자체 구현하기
Feed 지면에 진입한 시점에 노출할 광고가 없다면 광고 미할당 안내 UI가 표시됩니다. 미할당 안내 디자인은 자체 구현하여 변경할 수 있습니다.
...
광고 미할당 안내 디자인을 직접 구현하려면 다음의 절차를 따르세요.
Feed 지면에 광고가 할당되지 않았을 때의 화면에 추가할 에러 이미지(
feedErrorImageView
), 타이틀(feedErrorTitle
), 상세 설명(feedErrorDescription
) 레이아웃을 작성하세요.Code Block <!-- custom_feed_error_view.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="vertical" android:padding="40dp"> <ImageView android:id="@+id/feedErrorImageView" android:layout_width="match_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/feedErrorTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="32dp" android:textColor="@color/bz_text_emphasis" android:textSize="16sp" /> <TextView android:id="@+id/feedErrorDescription" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="8dp" android:textAlignment="center" android:textColor="@color/bz_text_description" android:textSize="14sp" /> </LinearLayout>
FeedErrorViewHolder
를 구현하는 커스텀 클래스CustomErrorView
를 새로 생성하고, 자동 완성되는GetView()
메소드를 다음과 같이 구현하세요.
.descriptionTextView(descriptionTextView)Code Block public class CustomErrorView extends FeedErrorViewHolder { @NonNull @Override public View getErrorView(@NonNull Activity activity) { // TODO: 1번에서 생성한 custom_feed_error_view 레이아웃을 inflate View errorView = activity.getLayoutInflater().inflate(R.layout.custom_feed_error_view, null, false); final ImageView errorImageView = errorView.findViewById(R.id.feedErrorImageView); final TextView errorTitle = errorView.findViewById(R.id.feedErrorTitle); final TextView errorDescription = errorView.findViewById(R.id.feedErrorDescription); errorImageView.setImageResource(R.drawable.bz_ic_feed_profile_coin); // 에러 이미지 설정 errorTitle.setText("타이틀: 광고가 없습니다. "); // 에러 타이틀 텍스트 설정 errorDescription.setText("디스크립션: 할당된 광고가 없습니다!"); // 에러 상세 텍스트 설정
.iconImageView(iconImageView) .ctaView(customCtaViewreturn errorView; }
}
FeedConfig
의feedErrorViewHolderClass
속성에 이전 단계에서 생성한CustomErrorView
클래스를 추가하세요.
.build();Code Block // Feed 지면 초기화 // TODO: feedErrorViewHolderClass 속성에 2번에서 생성한 CustomErrorView 클래스를 설정합니다. final FeedConfig feedConfig = new FeedConfig.Builder(YOUR_FEED_UNIT_ID)
viewBinder.bind(nativeAd);.feedErrorViewHolderClass(CustomErrorView.class)
}
//
...
생략
.. }.
build();
...
...
SDK에서 제공하는 DefaultCtaView
로 구현한 CTA 버튼의 디자인을 변경하려면 CTA 버튼 커스터마이징하기 토픽을 참고하세요.
사용자 프로필 입력 배너 노출 여부 설정하기
...
사용자가 출생연도 또는 성별 정보를 제공하지 않으면 헤더 영역에 프로필 정보를 입력하는 배너가 기본적으로 노출됩니다.
...
FeedConfig
를 수정하여 프로필 정보 입력 배너의 노출 여부를 설정할 수 있습니다.
다음은 프로필 입력 배너를 표시하지 않는 예시입니다.
...
Info |
---|
|
...