...
광고 분류 기능에 대한 설정은 앱에서 코드를 수정하거나 재배포 하지 재배포하지 않고 변경할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.
...
탭으로 분류할 수 있는 광고의 유형은 노출형 광고, 참여형 광고, 비디오 광고, 소셜미디어 광고, 쇼핑 광고입니다. 각 탭은 한 개 이상의 광고 유형으로 구성할 수 있습니다. 단, 쇼핑 광고의 경우 다른 광고 유형과 함께 탭으로 구성할 수 없습니다.
탭이 여러 개의 광고 유형으로 구성되면 ‘클릭하기’, ‘참여하기’ 등 광고 유형을 세분화하는 필터 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();
사용자 프로필 입력 배너 노출 여부 설정하기
...
사용자가 출생연도 또는 성별 정보를 제공하지 않으면 헤더 영역에 프로필 정보를 입력하는 배너가 기본적으로 노출됩니다. FeedConfig
를 수정하여 프로필 정보 입력 배너의 노출 여부를 설정할 수 있습니다. 다음은 프로필 입력 배너를 표시하지 않는 예시입니다.
CTA 버튼 자체 구현하기
BuzzAd Android용 SDK에서 기본으로 제공하는 UI를 사용하지 않고 직접 구현할 수 있습니다.
...
CTA 버튼을 직접 구현하려면 다음의 절차를 따르세요.
뷰 레이아웃(
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 광고에 반영하세요.
광고 디자인 자체 구현하기를 참고하여
CustomAdsAdapter
를 구현하세요.CustomAdsAdapter.onBindViewHolder
에서CustomCtaView
를 객체화하세요.NativeAdViewBinder.Builder
에 새로 생성한CustomCtaView
를 바인딩하세요.Code Block language java class CustomAdAdapter: AdsAdapter<AdsAdapter.NativeAdViewHolder>() { // 생략... 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()
메소드를 다음과 같이 구현하세요.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("디스크립션: 할당된 광고가 없습니다!"); // 에러 상세 텍스트 설정 return errorView; } }
FeedConfig
의feedErrorViewHolderClass
속성에 이전 단계에서 생성한CustomErrorView
클래스를 추가하세요.Code Block // Feed 지면 초기화 // TODO: feedErrorViewHolderClass 속성에 2번에서 생성한 CustomErrorView 클래스를 설정합니다. final FeedConfig feedConfig = new FeedConfig.Builder(YOUR_FEED_UNIT_ID) .feedErrorViewHolderClass(CustomErrorView.class) .build();
사용자 프로필 입력 배너 노출 여부 설정하기
사용자가 출생연도 또는 성별 정보를 제공하지 않으면 헤더 영역에 프로필 정보를 입력하는 배너가 기본적으로 노출됩니다.
...
FeedConfig
를 수정하여 프로필 정보 입력 배너의 노출 여부를 설정할 수 있습니다.
다음은 프로필 입력 배너를 표시하지 않는 예시입니다.
Code Block | ||
---|---|---|
| ||
final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID") .profileBannerEnabled(false) // 프로필 배너 미노출 .build(); |
Info |
---|
|
...