고급 설정
이 페이지에서는 피드 지면에서 구현할 수 있는 기능과 각 기능의 설정을 변경하는 방법을 확인할 수 있습니다.
지면 상의 기능을 변경하거나 구현하려면 SDK에서 제공하는 기본 UI를 사용하거나 직접 클래스를 구현해야 합니다. 클래스를 자체적으로 구현하려면 반드시 다음의 조건을 충족해야 합니다.
- 구현 클래스는 내부 클래스가 아니어야 합니다.
- 불가피하게 내부 클래스로 생성해야 할 경우,
public static
클래스로 구현해야 합니다.
피드를 구성하는 주요 기능들은 아래 그림과 같습니다.
광고 분류 기능
피드 광고 분류 기능은 탭과 필터 UI를 사용하여 유형 별로 분류된 광고를 사용자에게 보여주는 기능입니다. 탭과 필터 기능을 사용하면 사용자가 참여하고 싶은 유형의 광고만 볼 수 있어 사용자의 광고 참여 경험과 광고 효율을 높일 수 있습니다.
광고 분류 기능에 대한 설정은 앱에서 코드를 수정하거나 재배포하지 않고 변경할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.
광고 분류 탭과 필터
탭의 갯수, 탭의 이름, 탭으로 모아서 게재할 광고 유형을 설정할 수 있습니다. 탭은 최대 3개까지 설정할 수 있으며, 초기에는 광고 적립, 쇼핑 적립 탭이 설정됩니다. 이 중에서 광고 적립 탭에는 쇼핑 광고를 제외한 나머지 유형의 광고가 노출되며, 쇼핑 적립 탭에는 쇼핑 광고가 노출됩니다.
탭으로 분류할 수 있는 광고의 유형은 노출형 광고, 참여형 광고, 비디오 광고, 소셜 미디어 광고, 쇼핑 광고입니다. 각 탭은 한 개 이상의 광고 유형으로 구성할 수 있습니다. 단, 쇼핑 광고의 경우 다른 광고 유형과 함께 탭으로 구성할 수 없습니다.
탭이 여러 개의 광고 유형으로 구성되면 ‘클릭하기’, ‘참여하기’ 등 광고 유형을 세분화하는 필터 UI가 노출됩니다.
무한 스크롤 기능
피드 무한 스크롤 기능은 사용자가 피드에 진입해 할당된 광고 목록을 끝까지 스크롤 해 더 이상 볼 수 있는 광고가 없으면 자동으로 추가 광고를 할당하여 보여주는 기능입니다. 이 기능은 기본적으로 활성화되어 있으며, 앱에서 코드를 수정하거나 재배포를 하지 않고 무한 스크롤 기능의 활성화 여부를 설정할 수 있습니다. 설정을 변경하려면 버즈빌 담당자에게 연락하세요.
앱 UI에 진입 경로 추가
앱 화면의 아이콘, 버튼, 배너 등 레이아웃 UI에 뷰를 직접 구현하여 피드로 진입하는 경로를 만들 수 있습니다.
진입 경로를 생성할 수 있는 UI 컴포넌트의 예시는 아래 다이어그램을 참고하세요. 또한 샘플 앱에서 제공하는 다양한 커스텀 진입 경로들의 샘플 코드를 확인해 보세요.
준비 사항
- 피드 지면 기본 설정 완료
⚠️ 주의
진입 경로의 정상적인 동작을 위해서는 피드 지면 초기화하기 토픽의 설명에 따라 반드시BuzzAdBenefitConfig
에FeedConfig
를 추가해야 합니다.
진입 경로 추가하기
액티비티, 프래그먼트, 뷰 내부 등에 피드 진입 경로를 생성할 수 있습니다. 피드 진입 경로를 UI 레이아웃에 추가하려면 UI 레이아웃을 구현한 후 FeedEntryView
ViewGroup을 추가하세요.
XML로 진입 경로 구현하기
다음은 your_image
를 눌렀을 때 피드 지면이 열리도록 XML로 진입 경로를 구현한 예시입니다.
<?xml version="1.0" encoding="utf-8"?>
<!-- FeedEntryView을 추가합니다. -->
<com.buzzvil.buzzad.benefit.presentation.feed.entrypoint.FeedEntryView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:buzzvilFeedEntryViewName="your_custom_entry_point_1"> // 뷰에 대한 사용자 반응 추적
<!-- 직접 UI를 구현합니다. -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_image"
/>
</com.buzzvil.buzzad.benefit.presentation.feed.entrypoint.FeedEntryView>
액티비티에 동적으로 진입 경로 구현하기
레이아웃
다음은 res/layout
하위의 레이아웃 파일(feed_entry_point.xml
)에 진입 경로를 동적으로 구현한 예시입니다.
<?xml version="1.0" encoding="utf-8"?>
<!-- FeedEntryView를 추가합니다. -->
<com.buzzvil.buzzad.benefit.presentation.feed.entrypoint.FeedEntryView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:buzzvilFeedEntryViewName="your_custom_entry_point_1"> // 뷰에 대한 사용자 반응 추적
<!-- 직접 UI를 구현합니다. -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_image"
/>
</com.buzzvil.buzzad.benefit.presentation.feed.entrypoint.FeedEntryView>
액티비티 레이아웃
다음은 res/layout
하위의 액티비티 레이아웃 파일에 진입 경로를 동적으로 구현한 예시입니다.
<FrameLayout
android:id="@+id/entryPointPlaceholder"/>
액티비티 코드
다음은 액티비티 소스 코드 파일에 진입 경로를 동적으로 구현한 예시입니다.
final ViewGroup parent = findViewById(R.id.entryPointPlaceholder);
final FeedEntryView entryView = (FeedEntryView) getLayoutInflater().inflate(R.layout.feed_entry_point, null);
entryView.setFeedEntryViewName("your_custom_entry_point_1"); // 뷰에 대한 사용자 반응 추적
parent.addView(entryView);
적립 가능한 포인트 표시하기
아래 그림과 같이 적립 가능한 포인트를 표시하여 아직 피드에 진입하지 않은 사용자의 참여율을 높일 수 있습니다.
적립 가능한 포인트를 사용자에게 미리 보여 주려면, 아래 순서대로 구현하세요.
- 피드 광고를 할당하기 위해
buzzAdFeed.load()
를 호출하세요. - 광고 할당이 성공하면
onSuccess()
콜백 이벤트가 호출됩니다.
- 광고 할당 및 표시하기 토픽을 참고하세요.
onSuccess()
콜백 이벤트에서buzzAdFeed.getAvailableRewards()
를 호출하면, 적립 가능한 총 포인트 금액을 조회할 수 있습니다.- 위에서 조회한 적립 가능한 총 포인트 금액 값으로 뷰를 업데이트하세요.
다음은 onResume()
을 실행할 때마다 피드를 새로 고침하고 뷰를 업데이트하는 예시입니다.
✏️ 참고
사용자가 광고에 참여하여 리워드를 받거나 피드를 아래로 스크롤하여 새로운 광고를 불러올 경우, 피드 진입 뷰에 표시된 적립 가능한 포인트 값과 실제로 적립 가능한 포인트 값에 차이가 발생할 수도 있습니다.
private BuzzAdFeed buzzAdFeed;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
buzzAdFeed = new BuzzAdFeed.Builder().build();
}
@Override
protected void onResume() {
super.onResume();
buzzAdFeed.load(new BuzzAdFeed.FeedLoadListener() {
@Override
public void onSuccess() {
// 할당된 광고가 있으면 호출됩니다.
int feedTotalReward = buzzAdFeed.getAvailableRewards(); // 적립 가능한 총 포인트 금액
// TODO: 뷰 업데이트하는 함수를 호출합니다.
updateMessages(feedTotalReward);
}
@Override
public void onError(AdError error) {
// 할당된 광고가 없으면 호출됩니다.
// TODO: 적립 가능 포인트를 0으로 표시합니다.
updateMessages(0);
Log.e(TAG, "Failed to load a native ad.", error);
}
});
}
// TODO: 적립 가능한 총 포인트 금액 값으로 뷰를 업데이트하도록 구현합니다.
private void updateMessages(final int points) {
}
툴바 자체 구현하기
피드 툴바의 디자인을 변경할 수 있습니다. 툴바 영역의 UI를 변경하는 방법은 2가지입니다. SDK에서 제공하는 기본 UI를 사용하거나 Custom View를 구현하여 툴바의 디자인을 구현하세요.
✏️ 참고
프래그먼트(FeedFragment
)로 피드 지면을 연동한 경우에는 툴바를 자체 구현할 수 없습니다.
SDK 기본 UI 사용하기
BuzzAd Android용 SDK에서 제공하는 기본 UI를 수정하여 타이틀 혹은 배경색을 변경할 수 있습니다.
다음은 기본 UI를 수정하여 툴바를 변경하는 예시입니다. 이 예시에서는 DefaultFeedToolbarHolder
를 상속받은 클래스를 구현하고, 기본 UI인 FeedToolbar
를 사용하여 타이틀 혹은 배경색을 변경합니다. 그리고 FeedConfig
에 구현한 클래스를 추가합니다.
public class YourFeedToolbarHolder extends DefaultFeedToolbarHolder {
@Override
public View getView(Activity activity, @NonNull final String unitId) {
super.toolbar = new FeedToolbar(activity); // FeedToolbar 에서 제공하는 기본 템플릿을 사용합니다.
toolbar.setTitle("YourFeedToolbarHolder");
toolbar.setIconResource(R.drawable.your_icon); // 이미지 사이즈 규격은 24dp 입니다.
toolbar.setBackgroundColor(Color.parseColor("#123456"));
super.addInquiryMenuItemView(activity); // 문의하기 버튼은 이 함수를 통해 추가할 수 있습니다.
super.addSettingsMenuItemView(activity); // 세팅 버튼은 이 함수를 통해 추가할 수 있습니다.
addRightMenuItemView1(activity); // 커스터마이징한 버튼 추가할 수 있습니다.
return toolbar;
}
// 커스터마이징한 버튼을 추가하려면 DefaultMenuLayout 를 사용하여 View 를 생성하고
// toolbar.addRightMenuButton 를 사용하여 toolbar 에 추가합니다.
private void addRightMenuItemView1(@NonNull final Activity activity) {
MenuLayout menuLayout = new DefaultMenuLayout(activity, R.mipmap.ic_launcher);
menuLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showInquiry(); // showInquiry 를 호출하여 문의하기 페이지로 연결합니다.
}
});
toolbar.addRightMenuButton(menuLayout);
}
}
final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.feedToolbarHolderClass(YourFeedToolbarHolder.class)
.build();
직접 구현한 Custom View 사용하기
BuzzAd Android용 SDK에서 제공하는 UI를 사용하지 않고 직접 Custom View를 구현하여 툴바의 디자인을 변경할 수 있습니다.
Custom View를 직접 생성하여 툴바를 변경하려면 다음의 절차를 따르세요.
DefaultFeedToolbarHolder
의 서브클래스를 생성하세요.- 툴바 Custsom View를
your_toolbar_holder_layout.xml
에 구현하세요.
public class YourFeedToolbarHolder extends DefaultFeedToolbarHolder {
@Override
public View getView(final Activity activity, @NonNull final String unitId) {
final LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.your_toolbar_holder_layout, null);
}
@Override
public void onTotalRewardUpdated(int totalReward) {
// 적립 가능한 리워드를 UI에 적용할 수 있습니다.
}
}
✏️ 참고
DefaultFeedToolbarHolder
에는 액션형 광고의 사용자 문의를 처리하기 위한 문의하기 페이지를 연결하는showInquiry();
함수가 기본적으로 포함되어 있습니다. 그러므로 Custom View로 구현하는 FeedToolbar도showInquiry();
를 호출하여 문의하기 페이지를 연결할 수 있습니다.
FeedConfig
객체를 생성한 후feedToolbarHolderClass()
에DefaultFeedToolbarHolder
서브클래스를 추가하세요.
final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.feedToolbarHolderClass(YourFeedToolbarHolder.class)
.build();
직접 구현한 툴바 높이 값 수정하기
Custom View의 높이가 안드로이드 액티비티의 기본 액션바 높이와 다를 경우, 직접 구현한 View가 정상적으로 보이지 않을 수 있습니다. 이 경우에는 BuzzAdFeedTheme
객체의 toolbarHeight()
속성에서 툴바의 높이 값을 수정하세요.
final BuzzAdFeedTheme buzzAdFeedTheme =
BuzzAdFeedTheme.getDefault()
.toolbarHeight(R.dimen.YOUR_TOOL_BAR_HEIGHT);
BuzzAdFeed.setDefaultTheme(buzzAdFeedTheme);
헤더 영역 자체 구현하기
피드 헤더 영역을 자유롭게 활용할 수 있습니다. 예를 들어, 피드 영역을 설명하는 공간으로 활용하거나 적립 가능한 금액을 표시할 수도 있습니다.
✏️ 참고
헤더 영역을 구현하지 않으면총 적립 가능 금액
을 보여주는 기본 헤더가 표시됩니다.
헤더 영역을 사용하지 않으려면 아래 내용을 참고하여 Custom View(your_feed_header_layout
)의 높이가 0인 비어있는 뷰를 적용하세요.
다음은 헤더 영역을 변경하는 예시입니다.
FeedHeaderViewAdapter
인터페이스를 구현하는 클래스를 생성하고 Custom View(your_feed_header_layout
)를 헤더 영역에 구현합니다. 그리고 FeedConfig
의 feedHeaderViewAdapterClass()
속성에 새로 구현한 클래스를 추가합니다.
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.
final TextView textView = view.findViewById(R.id.your_textview);
textView.setText(String.format("리워드 %d원", reward));
}
@Override
public void onDestroyView() {
// Use this this callback for clearing memory
}
}
final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapter.class)
.build();
기본 적립 포인트 알림 팝업 자체 구현하기
사용자가 광고에 참여하지 않아도 피드에 접근하면 일정 주기마다 포인트를 지급합니다. 기본 포인트 지급 알림 팝업을 직접 구현하고 디자인을 변경하여 사용자 경험을 개선할 수 있습니다.
다음은 기본 적립 포인트 지급 알림 팝업을 직접 구현하는 예시입니다.
BaseRewardNotificationAdapter
인터페이스를 구현하는 클래스를 생성하세요.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 + " 포인트가 적립되었습니다.");
}
}이전 단계에서 생성한
CustomBaseRewardNotificationAdapter
를FeedConfig
에 설정하세요.final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.baseRewardNotificationAdapterClass(CustomBaseRewardNotificationAdapter.class)
.build();
광고 디자인 자체 구현하기
BuzzAd Android용 SDK에서 제공하는 광고는 일반 광고와 쇼핑 광고가 있습니다.
- 일반 광고: 쇼핑 광고를 제외한 나머지 유형의 광고입니다.
- 쇼핑 광고: 사용자가 광고를 통해 물건 구매를 달성하는 경우 사용자에게 구매 금액의 일정 비율을 포인트로 돌려주는 광고입니다.
두 유형 모두 광고를 표현할 수 있는 다양한 정보로 구성됩니다. 일반 광고와 쇼핑 광고를 구성하는 요소와 UI에 대해서는 아래의 표를 참고하세요.
광고 유형 | 구성 요소 | 설명 |
---|---|---|
공통(일반, 쇼핑) | 광고 제목 (필수) | 광고의 제목입니다. 최대 10자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다. |
광고 소재 (필수) |
| |
광고 설명 (필수) | 광고에 대한 상세 설명입니다. 최대 40자까지 권장하며, 필요에 따라 글자 수에 상관 없이 일정 부분은 생략 부호로 대체할 수 있습니다. | |
광고주 아이콘 (필수) |
| |
CTA 버튼 (필수) |
✏️ 참고 CTA 버튼의 디자인을 변경하려면 CTA 버튼 커스터마이징하기 토픽을 참고하세요. | |
광고 알림 문구 (권장) | 광고임을 명시하는 문구입니다. (예: 광고 , ad , 스폰서 , Sponsored ) | |
쇼핑 적립 | OriginalPrice View (권장) | 상품의 원가를 표시합니다. |
Price View (권장) | 상품의 할인된 가격을 표시합니다. | |
DiscountRate View (권장) | 상품 가격의 할인율을 표시합니다. 할인율은 원가와 할인가로 비교하여 산출해서 표시해야 합니다. |
일반 광고 디자인 자체 구현하기
일반 광고의 디자인을 변경하려면 다음의 절차를 따르세요.
일반 광고용
NativeAdView
의 규격에 맞는 레이아웃(your_feed_ad.xml
)을 구현하세요.<!-- your_feed_ad.xml -->
<com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView
android:id="@+id/native_ad_view" ...>
<!-- MediaView와 DefaultCtaView는 NativeAdView의 하위 컴포넌트로 구현해야 합니다. -->
<LinearLayout ... >
<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" ... />
<com.buzzvil.buzzad.benefit.presentation.media.DefaultCtaView
android:id="@+id/ctaView" ... />
</LinearLayout>
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>AdsAdapter
의 상속 클래스를 구현하세요.
onCreateViewHolder
에서your_feed_ad.xml
을 사용하여NativeAdView
를 생성하세요.onBindViewHolder
에서NativeAdViewBinder
를 이용하여 광고 데이터(NativeAd
)를 앞서 생성한NativeAdView
에 바인딩하세요.public class CustomAdsAdapter 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, 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 MediaView mediaView = view.findViewById(R.id.mediaView);
final TextView titleView = view.findViewById(R.id.textTitle);
final ImageView iconView = view.findViewById(R.id.imageIcon);
final TextView descriptionView = view.findViewById(R.id.textDescription);
final DefaultCtaView ctaView = view.findViewById(R.id.ctaView);
// 광고 데이터(NativeAd)를 바인딩합니다.
final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(view, mediaView)
.titleTextView(titleView)
.descriptionTextView(descriptionView)
.iconImageView(iconView)
.ctaView(ctaView)
.build();
viewBinder.bind(nativeAd);
}
}NativeAdEventListener
를 통해 광고 콜백 이벤트 수신 기능을 부가적으로 추가할 수도 있습니다.✏️ 참고
리워드 적립 결과(RewardResult
) 종류는 리워드 적립 결과(RewardResult
) 종류를 참고하세요.public class CustomAdsAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> {
private NativeAdEventListener listener;
// 부가 기능: 광고 콜백 이벤트 수신 기능을 추가합니다.
@Override
public void onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) {
...생략...
viewBinder.bind(nativeAd);
if (listener != null) {
nativeAd.removeNativeAdEventListener(listener);
}
listener = buildNativeAdEventListener(holder.itemView);
nativeAd.addNativeAdEventListener(listener);
}
private NativeAdEventListener buildNativeAdEventListener(@NonNull View view) {
return new NativeAdEventListener() {
@Override
public void onImpressed(final @NonNull NativeAd nativeAd) {
}
@Override
public void onClicked(@NonNull NativeAd nativeAd) {
}
@Override
public void onRewardRequested(@NonNull NativeAd nativeAd) {
}
@Override
public void onRewarded(@NonNull NativeAd nativeAd, @Nullable RewardResult nativeAdRewardResult) {
Toast.makeText(view.getContext(), "onRewarded: " + nativeAdRewardResult, Toast.LENGTH_SHORT).show();
}
@Override
public void onParticipated(final @NonNull NativeAd nativeAd) {
}
};
}
}
FeedConfig
에 위에서 작성한CustomAdsAdapter
를 광고 어댑터 클래스로 설정하세요.final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
.adsAdapterClass(CustomAdsAdapter.class)
.build();
쇼핑 적립 광고 디자인 자체 구현하기
쇼핑 적립 광고의 디자인을 변경하려면 다음의 절차를 따르세요.
일반 광고용 레이아웃에
discountedPriceText
,originalPriceText
,discountPercentageText
를 추가하여 쇼핑 적립 광고용NativeAdView
의 규격에 맞는 레이아웃(your_feed_ad_cps.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" ...>
<!-- MediaView와 DefaultCtaView는 NativeAdView의 하위 컴포넌트로 구현해야 합니다. -->
<LinearLayout ... >
<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" ... />
<com.buzzvil.buzzad.benefit.presentation.media.DefaultCtaView
android:id="@+id/ctaView" ... />
<!-- 쇼핑 적립 광고 구성 요소를 추가하세요 -->
<TextView
android:id="@+id/discountedPriceText"
...생략... />
<TextView
android:id="@+id/originalPriceText"
...생략... />
<TextView
android:id="@+id/discountPercentageText"
...생략... />
</LinearLayout>
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>일반 광고 디자인 자체 구현하기 토픽을 참고해
AdsAdapter
의 상속 클래스를 구현하세요.
다음의 예시 코드를 참고하세요.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 MediaView mediaView = view.findViewById(R.id.mediaView);
final TextView titleView = view.findViewById(R.id.textTitle);
final ImageView iconView = view.findViewById(R.id.imageIcon);
final TextView descriptionView = view.findViewById(R.id.textDescription);
final DefaultCtaView ctaView = view.findViewById(R.id.ctaView);
final TextView discountedPriceText = view.findViewById(R.id.discountedPriceText);
final TextView originalPriceText = view.findViewById(R.id.originalPriceText);
final TextView discountPercentageText = view.findViewById(R.id.discountPercentageText);
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);
}
}
// 광고 데이터(NativeAd)를 바인딩합니다.
final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(view, mediaView)
.titleTextView(titleView)
.descriptionTextView(descriptionView)
.iconImageView(iconView)
.ctaView(ctaView)
// 부가 기능: 텍스트를 클릭할 수 있도록 설정합니다.
.addClickableView(discountPercentageText)
.addClickableView(discountedPriceText)
.addClickableView(originalPriceText)
.build();
viewBinder.bind(nativeAd);
}
private String getCommaSeparatedPrice (long price){
return String.format(Locale.getDefault(), "₩%,d", price);
}
}FeedConfig
에 위에서 작성한CustomCPSAdsAdapter
를 쇼핑 적립형 광고 어댑터 클래스로 설정하세요.final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.cpsAdsAdapterClass(YourCPSAdsAdapter.class)
.build();
CTA 버튼 자체 구현하기
BuzzAd Android용 SDK에서 기본으로 제공하는 UI를 사용하지 않고 CTA 버튼을 자체적으로 구현할 수 있습니다.
CTA 버튼을 직접 구현하려면 다음의 절차를 따르세요.
✅ 중요
v3.0.0, v3.0.1 또는 v3.1.0, v3.1.1을 연동한 후 아직 최신 패치 버전으로 업데이트하지 않은 경우, 하단의 CTA 버튼 자체 구현하기(v3.0.0, v3.0.1, v3.1.0, v3.1.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>CtaView
클래스를 상속하는 서브클래스인CustomCtaView
를 생성하세요.CtaView
클래스에서 사용하던 CTA View 레이아웃을inflate
하도록 구현하세요.사용자의 광고 참여 상태에 따라 호출되는 아래의 오버라이딩 메소드에서 CTA 버튼의 아이콘 이미지, 텍스트, 리워드 값을 구현하세요.
renderViewParticipatingState
: 사용자가 광고에 참여 중인 상태 (예: 액션형 광고의 랜딩 페이지에 진입한 상태)renderViewParticipatedState
: 사용자가 광고 참여를 완료한 상태renderViewRewardAvailableState
: 사용자가 아직 광고에 참여하지 않은 상태renderViewRewardNotAvailableState
: 사용자가 획득할 리워드가 없는 광고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 광고 레이아웃에 설정하세요.
다음은 피드 광고의 레이아웃 예시입니다.<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"/>
<!-- TODO: 새로 생성한 CustomCtaView 클래스 경로를 설정합니다. -->
<com.your.packagename.CustomCtaView
android:id="@+id/customCtaView"/>
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>다음 순서에 따라 직접 구현한 CTA 버튼을 피드 광고에 반영하세요.
i. 광고 디자인 자체 구현하기를 참고하여
CustomAdsAdapter
를 구현하세요.ii.
CustomAdsAdapter.onBindViewHolder
에서CustomCtaView
를 객체화하세요.iii.
NativeAdViewBinder.Builder
에 새로 생성한CustomCtaView
를 바인딩하세요.class CustomAdAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> {
// 생략...
@Override
public void onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) {
super.onBindViewHolder(holder, nativeAd);
// 생략...
final CustomCtaView ctaView = view.findViewById(R.id.ctaView);
final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(view, mediaView)
// 생략...
.ctaView(customCtaView)
.build();
viewBinder.bind(nativeAd);
}
}
✏️ 참고
SDK에서 제공하는DefaultCtaView
로 구현한 CTA 버튼의 디자인을 변경하려면 CTA 버튼 커스터마이징하기 토픽을 참고하세요.
⚠️ 주의
CustomCtaView
클래스는 난독화 되지 않도록 Proguard 설정에서 제외해야 합니다. Proguard 설정 파일에 다음 라인을 추가하세요.-keep class com.your.packagename.CustomCtaView { *; }
CTA 버튼 자체 구현하기(v3.0.0, v3.0.1, v3.1.0, v3.1.1)
v3.0.0, v3.0.1 또는 v3.1.0, v3.1.1을 연동한 후 아직 최신 패치 버전으로 업데이트하지 않은 경우,아래 절차에 따라 CTA 버튼을 직접 구현할 수 있습니다.
뷰 레이아웃(
view_customized_cta.xml
)을 구현하세요. 다음은 레이아웃 리소스로 뷰 레이아웃을 구현한 예시입니다.<!-- view_customized_cta.xml -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
...(생략)...>
<TextView
android:id="@+id/textCta"
...(생략)...
tools:text="CTA 텍스트"/>
<ImageView
android:id="@+id/imageReward"
android:layout_width="24dp"
android:layout_height="24dp"
android:src=[아이콘 이미지 리소스] />
<TextView
android:id="@+id/textReward"
...(생략)...
tools:text="+1"/>
</LinearLayout>CtaView
를 상속하는 서브클래스를 생성하세요.다음은 CTA View 클래스를 생성한 예시입니다.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);
inflate(getContext(), R.layout.bz_view_customized_cta, this);
this.rewardImageView = findViewById(R.id.imageReward);
this.rewardTextView = findViewById(R.id.textReward);
this.ctaTextView = findViewById(R.id.textCta);
}
@NonNull
@Override
public TextView rewardTextView() {
return rewardTextView;
}
@NonNull
@Override
public TextView ctaTextView() {
return ctaTextView;
}
@NonNull
@Override
public ImageView rewardImageView() {
return rewardImageView;
}
}피드 광고 레이아웃에서 자체 구현한 CTA 뷰를 사용하세요.다음은 레이아웃 예시입니다.
<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"/>
<!-- CtaView 서브클래스로 Cta View를 등록합니다. -->
<com.your.packagename.CustomCtaView
android:id="@+id/customCtaView"/>
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>CustomCtaView
객체에 위에서 설정한 CTA View를 가져오고,NativeAdViewBinder
에서 광고 데이터를 바인딩하세요.final NativeAdView nativeAdView = findViewById(R.id.your_native_ad_view);
// TODO: CustomCtaView로 위의 CTA View를 가져옵니다.
final CustomCtaView customCtaView = nativeAdView.findViewById(R.id.customCtaView)
.ctaView(customCtaView) ; // TODO: customCtaView로 설정합니다.
// TODO: 광고 데이터를 바인딩합니다.
final NativeAdViewBinder viewBinder = new NativeAdViewBinder.Builder(nativeAdView, mediaView)
.ctaView(customCtaView) // customCtaView로 설정합니다.
.build();
광고 미할당 안내 디자인 자체 구현하기
피드 지면에 진입한 시점에 노출할 광고가 없다면 광고 미할당 안내 UI가 표시됩니다. 미할당 안내 디자인은 자체 구현하여 변경할 수 있습니다.
광고 미할당 안내 디자인을 직접 구현하려면 다음의 절차를 따르세요.
피드 지면에 광고가 할당되지 않았을 때의 화면에 추가할 에러 이미지(
feedErrorImageView
), 타이틀(feedErrorTitle
), 상세 설명(feedErrorDescription
) 레이아웃을 작성하세요.<!-- 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()
,updateErrorView()
메소드를 다음과 같이 구현하세요.public class CustomErrorView extends FeedErrorViewHolder {
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);
@NonNull
@Override
public View getErrorView(@NonNull Activity activity) {
// TODO: 1번에서 생성한 custom_feed_error_view 레이아웃을 inflate
errorImageView.setImageResource(R.drawable.bz_ic_feed_profile_coin); // 에러 이미지 설정
errorTitle.setText("타이틀: 광고가 없습니다. "); // 에러 타이틀 텍스트 설정
errorDescription.setText("디스크립션: 할당된 광고가 없습니다!"); // 에러 상세 텍스트 설정
return errorView;
}
@Override
public updateErrorView(AdErrorType adErrorType) {
// TODO: 위에서 선언한 View를 업데이트 할 수 있는 코드를 작성하세요.
...
}
}FeedConfig
의feedErrorViewHolderClass
속성에 이전 단계에서 생성한CustomErrorView
클래스를 추가하세요.// Feed 지면 초기화
// TODO: feedErrorViewHolderClass 속성에 2번에서 생성한 CustomErrorView 클래스를 설정합니다.
final FeedConfig feedConfig = new FeedConfig.Builder(YOUR_FEED_UNIT_ID)
.feedErrorViewHolderClass(CustomErrorView.class)
.build();
광고 타입 확인하기
BuzzAd Android용 SDK는 노출형, 액션형 등 다양한 광고 유형별로 차별화된 리워드 제공 등 다양한 기획을 지원하기 위해 광고 유형을 확인할 수 있는 API를 제공합니다. API에 대한 자세한 내용은 자주 하는 질문의 광고 타입 확인하기를 참고하세요.
개인정보 제3자 제공 동의 UI
✅ 중요
버즈빌과 개인정보 위수탁 관계이며 앱에서 자체적으로 제공하는 개인정보 처리방침 정책에 버즈빌을 수탁자로 포함하고 있다면, 여기에서 안내하는 개인정보 제3자 제공 동의 UI를 띄우지 않아도 됩니다.
기존에 제공하던 함수가 Deprecated 되었고, BuzzAd Android v3.27.x 부터는 아래의 코드는 삭제하는것을 권장합니다. 아래 코드가 없더라도 원격 제어가 가능합니다.
BuzzAdBenefit.getPrivacyPolicyManager()
PrivacyPolicyManager.showConsentUI()
PrivacyPolicyManager.grantConsent()
PrivacyPolicyManager.revokeConsent()
PrivacyPolicyManager.isConsentGranted()
❗️ DEPRECATED
BuzzAd Android용 SDK v3.27.x부터는 서버에서 개인정보 제3자 제공 동의 UI 표시를 제어합니다. BuzzAd Android용 SDK v3.27.x에서 표시 여부를 설정하려면 버즈빌 담당자에게 연락하세요.
개인 정보 보호법과 구글 정책에 따라, 개인 정보 수집 및 사용에 대한 사용자의 동의가 필요합니다. BuzzAd Android용 SDK는 동의를 얻기 위한 UI를 제공하며, 사용자가 개인 정보 수집에 동의하지 않으면, 피드 지면에 광고가 할당되지 않습니다. 피드 지면에 처음 진입한 사용자에게는 아래와 같은 UI가 표시됩니다.
사용자 프로필 입력 배너 노출 여부 설정하기
사용자가 출생연도 또는 성별 정보를 제공하지 않으면 헤더 영역에 프로필 정보를 입력하는 배너가 기본적으로 노출됩니다.
FeedConfig
를 수정하여 프로필 정보 입력 배너의 노출 여부를 설정할 수 있습니다.
다음은 프로필 입력 배너를 표시하지 않는 예시입니다.
final FeedConfig feedConfig = new FeedConfig.Builder("YOUR_FEED_UNIT_ID")
.profileBannerEnabled(false) // 프로필 배너 미노출
.build();
✏️ 참고
FeedConfig.feedHeaderViewAdapterClass
를 자체 구현하는 경우에는 프로필 입력 배너 노출 여부를 설정할 수 없습니다.
프래그먼트로 피드 연동하기
더 다양한 연동 방식을 제공하기 위해 BuzzAd Android용 SDK는 피드 지면을 제공하는 기본 방식인 액티비티 외에도 프래그먼트를 통한 연동을 지원합니다.
프래그먼트로 피드 지면을 연동하려면, 액티비티에 프래그먼트를 추가하고 해당 액티비티의 onCreate()
에서 프래그먼트를 초기하세요.
다음은 FeedFragment
를 연동하는 예시입니다.
class YourActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your);
// 광고를 새로 할당 받기 위해 필요한 부분입니다.
final BuzzAdFeed buzzAdFeed = new BuzzAdFeed.Builder().build();
final FeedFragment feedFragment = buzzAdFeed.getFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content, feedFragment)
.commitAllowingStateLoss();
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--activity_your.xml-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".feed.FeedFragmentActivity">
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
✏️ 참고
FeedFragment
의 UI를 변경하려면 디자인 커스터마이징 토픽을 참고하세요.