Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

개요

Feed의 구성 컴포넌트는 다음과 같이 구분합니다같습니다.

...

FeedToolbarHolder, AdsAdapter, FeedHeaderViewAdapter class의 custom class를 생성할때 다음 조건중 하나를 사용해야합니다.

...

Table of Contents
minLevel1
maxLevel7
exclude개요
Note

이하 가이드에서 커스터마이징을 위해 구현 클래스를 정의합니다. 구현하는 클래스는 아래의 조건을 충족해야합니다. 아래 조건을 충족하지 않는 경우 커스터마이징이 적용되지 않습니다.

  • 구현 클래스는 내부 클래스(Inner 클래스)가 아니어야 합니다.

  • Inner class로 만일 내부 클래스로 생성을 해야할 경우, public static class로 선언이 되어야 합니다.

위의 조건에 맞지 않는 경우, class를 찾지못하는 현상이 발생하여 customization이 적용되지 않습니다.

툴바 커스터마이징

Feed 상단의 툴바를 커스터마이징할 수 있습니다.

FeedToolbarHolderinterface를 구현하는 Class 를 생성합니다.

...

languagejava

...

  • 정적(static) 클래스로 구현해야합니다.

툴바(Toolbar)

<< 툴바 확대 이미지>>

FeedToolbarHolder.getView에 새로운 View로 반환하여 Feed 툴바 영역의 디자인을 변경할 수 있습니다.

SDK에서 기본으로 제공하는 툴바 View(FeedActivityToolbar)를 수정하면 간단히 타이틀 혹은 배경색을 변경할 수 있습니다. 더 자유로운 수정을 원하시는 경우에는 FeedActivityToolbar를 이용하지 않고 View 직접 작성하여 변경할 수 있습니다. (단, View의 높이가 액티비티의 기본 액션바 높이와 다를 경우 정상적으로 보이지 않을 수 있습니다. 이 경우에는 Theme 을 설정하여 액션바 높이를 수정해야합니다.)

FeedActivityToolbar를 이용한 변경 예시는 아래와 같습니다.

Code Block
languagejava
public class YourFeedToolbarHolder implements FeedToolbarHolder {
    private FeedActivityToolbar toolbar;

    @Override
    public View getView(final Activity activity, @NonNull final String unitId) {
        

...

this.toolbar = new FeedActivityToolbar(activity, unitId);
        toolbar.setTitle("BuzzAd Feed");
        

...

toolbar.setBackgroundColor(Color.parseColor("#1290FF")); // 

...

변경하려는 

...

"색상코드" 

...

 

...

입력

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

return 

...

toolbar;

...

 

...

   }

    

...

@Override

...

 

...

 

...

 

...

 public void onTotalRewardUpdated(int totalReward) {
   

...

 }
}
Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
      .feedToolbarHolderClass(YourFeedToolbarHolder.class)
     

...

 

...

.build();

필요에 따라, Theme을 적용하여 안드로이드의 Toolbar 의 높이를 수정합니다.

Code Block
languagexml
// AndroidManifest.xml

...생략...

<activity
    

...

android:name="com.buzzvil.buzzad.benefit.presentation.feed.FeedBottomSheetActivity"
    

...

android:theme="@style/YourActivityTheme"
    tools:replace="android:theme"/>
    

...

...생략...
Code Block
languagexml
// 

...

styles.xml

...

FeedConfig에 CustomFeedToolbarHolder를 설정합니다.

...

languagejava

...

<style name="YourActivityTheme" parent=...>
    ...생략...
    
    <item name="actionBarSize">DESIRED_ACTION_BAR_HEIGHT</item>
    
    ...생략...

...

툴바 Height 변경

커스터마이징한 FeedToolbarHolder가 들어가는 layout의 height값이 기본값으로 고정되어 있습니다.
아래 가이드를 통해 툴바의 height 값을 수정할 수 있습니다.

Code Block
languagexml
// AndroidManifest.xml

...생략...
<activity
    android:name="com.buzzvil.buzzad.benefit.presentation.feed.FeedBottomSheetActivity"
    android:theme="@style/MyAppTheme"
    tools:replace="android:theme"/>
...생략...
Code Block
languagexml
// styles.xml
<style name="MyAppTheme" parent=...>
    ...생략...
    <!-- Customize your theme here. -->
    <item name="actionBarSize">DESIRED_ACTION_BAR_HEIGHT</item>
    ...생략...
</style>

헤더 커스터마이징

Feed 상단의 헤더 영역을 커스터마이징하여, 유저에게 피드가 어떤 공간인지 상세히 안내할 수 있습니다.

FeedHeaderViewAdapter interface 를 구현하는 Class 를 생성합니다.

...

languagejava

...

</style>

헤더

<< 헤더 확대 이미지>>

Feed 헤더 영역을 자유로이 활용할 수 있습니다. 예를 들어, Feed 영역을 설명하는 공간으로도 활용할 수 있습니다.

헤더 영역을 수정하는 방법은 아래와 같습니다.
새 레이아웃(your_feed_header_layout)을 사용하는 구현 클래스를 작성합니다. 그리고, FeedConfigFeedHeaderViewAdapter에 작성한 구현 클래스를 설정합니다.

Code Block
languagejava
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 View rewardLayout = view.findViewById(R.

...

id.rewardLayout);
    

...

    if (reward 

...

== 0) 

...

{
 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

   rewardLayout.setVisibility(View.GONE);
     

...

 

...

 

...

 

...

} 

...

else 

...

{

...

 

...

 

...

         

...

 rewardLayout.setVisibility(View.VISIBLE);

...

 

...

           final TextView rewardTextView = view.findViewById(R.id.

...

rewardText);
            final 

...

String 

...

rewardText =

...

 

...

view.getContext().getString(R.string.bz_feed_header_view_reward_text, reward);
            

...

rewardTextView.

...

setText(

...

rewardText);
        }

...

 

...

   }
    
    

...

@Override 
    public void onDestroyView() {
    

...

  

...

 

...

 

...

// Use this this callback for clearing memory 
    }
}
Code Block
languagejava
final 

...

FeedConfig 

...

feedConfig = new 

...

FeedConfig.

...

Builder(context, "YOUR_FEED_UNIT_ID")
      .feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapter.class)
     

...

 .

...

build(

...

);

Feed Tab이 활성화되어 있는 경우, 아래의 방법으로 Tab의 UI를 바꿀 수 있습니다.

...

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
  

...

    .tabUiEnabled(true) 

...

    // set tabUiEnabled to true
 

...

     

...

FeedConfigFeedHeaderViewAdapter를 설정합니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    ...생략...
    .feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapter.class)
    .build();

...

.tabTextArray(new String[] { FIRST_TAB_NAME, SECOND_TAB_NAME }) // 탭에 들어갈 문구
      .build();

Tab의 색상을 변경하기 위해서는 https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/2164329086/ver%2B2.23.x%2B9.#PrimaryColor-%EB%B3%80%EA%B2%BD 를 통해 변경할 수 있습니다.

필터

...

Filter의 색상을 변경하기 위해서는 https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/2164329086/ver%2B2.23.x%2B9.#PrimaryColor-%EB%B3%80%EA%B2%BD 를 통해 변경할 수 있습니다.

광고 아이템 커스터마이징: 일반 광고

<<일반 광고과 쇼핑광고이미지 (일반광고 강조)>>

버즈빌 SDK에서 제공하는 광고는 일반광고와 쇼핑 적립 광고가 있습니다. 아래 가이드는 일반 광고의 디자인을 변경하는 방법을 설명합니다.

  1. 아래 NativeAdView을 포함하는 레이아웃(your_feed_ad.xml)을 구현합니다.

    NativeAdView의 레이아웃

    Code Block
    // your_feed_ad.xml
    
    
    <com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView
        android:id="@+id/native_ad_view"
        ...생략... >
        <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.CtaView
                android:id="@+id/ctaView"
                ...생략... />
        ...생략...
        </LinearLayout>
        ...생략...
    </com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>

  2. onCreateViewHolder에서 NativeAdViewHolderNativeAdView를 설정합니다.

  3.  onBindViewHolder에서는 NativeAdView에 광고 데이터(NativeAd)를 바인딩합니다.

    • clickableViews 리스트에 UI 컴포넌트를 추가하여, 클릭 이벤트를 수신할 컴포넌트를 설정합니다. 추가된 UI 컴포넌트를 클릭 시 광고 페이지로 이동하게 됩니다.

    • CTA 버튼은 CtaPresenter 를 이용하여 상황에 맞는 적절한 문구로 변경됩니다.
      CTA 버튼의 UI 혹은 문구의 커스터마이징은 가이드에 따라 진행할 수 있습니다.

    • OnNativeAdEventListener 를 통해 광고 콜백 이벤트를 수신할 수 있습니다.
      기획에 따라 추가로 UI 등을 추가할 수 있습니다.

...

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    ...생략...     .adsAdapterClass(CustomAdsAdapter.class)
      .build();

광고 아이템

...

커스터마이징

...

: 쇼핑 적립 광고

...

<<일반 광고과 쇼핑광고이미지 (일반광고 강조)>>

버즈빌 SDK에서 제공하는 광고는 일반광고와 쇼핑 적립 광고가 있습니다. 아래 가이드는 쇼핑 적립 광고의 디자인을 변경하는 방법을 설명합니다. 쇼핑 적립 광고는 일반 광고에 비해 많은 정보를 제공합니다. 일반 광고용 레이아웃에서 레이아웃에는 없는 priceText, originalPriceText, discountPercentageText, categoryText 가 추가되었습니다. 따라서 위 4가지 컴포넌트에 대해 추가로 데이터를 처리해야합니다 categoryText 가 있습니다.

  • NativeAdView(쇼핑 적립 광고) 의 레이아웃

...

Info

위에서 안내한 AdsAdapter 를 참고하여 수정합니다.

Code Block
languagejava
public class CustomCPSAdsAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> {

    @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) {
        final NativeAdView view = (NativeAdView) holder.itemView;
        final Ad ad = nativeAd.getAd();
        
        // create ad component
        ...생략...
        final TextView priceText = view.findViewById(R.id.discountedPriceText);
        final TextView originalPriceText = view.findViewById(R.id.originalPriceText);
        final TextView discountPercentageText = view.findViewById(R.id.discountPercentageText);
        final TextView categoryText = view.findViewById(R.id.categoryText);

        // data binding 
        ...생략...
        final Product product = ad.getProduct();
        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);
            }
            categoryText.setText(product.getCategory());
            if (!TextUtils.isEmpty(product.getCategory())) {
                categoryText.setVisibility(View.VISIBLE);
            }
        }

        final Collection<View> clickableViews = new ArrayList<>();
        clickableViews.add(ctaView);
        clickableViews.add(mediaView);
        clickableViews.add(descriptionView);

        view.setMediaView(mediaView);
        view.setClickableViews(clickableViews);
        view.setNativeAd(nativeAd);
        
        ...생략...
    }

    private String getCommaSeparatedPrice (long price){
        return String.format(Locale.getDefault(), "₩%,d", price);
    }
}

FeedConfig에 구현한 CustomCPSAdsAdapter를 설정합니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    ...생략...
    .cpsAdsAdapterClass(CustomCPSAdsAdapter.class)
    .build();

Tab 커스터마이징

Feed Tab이 활성화되어 있는 경우, 아래의 방법으로 Tab의 UI를 바꿀 수 있습니다.

...


}

FeedConfig에 구현한 CustomCPSAdsAdapter를 설정합니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    ...생략...
    .tabUiEnabled(true)     // set tabUiEnabled to true
    .tabTextArray(new String[] { FIRST_TAB_NAME, SECOND_TAB_NAME }) // 탭에 들어갈 문구)
      .cpsAdsAdapterClass(CustomCPSAdsAdapter.class)
      .build();

Tab의 UI 색상을 변경하기 위해서는 Theme 커스터마이징 가이드를 통해 변경할 수 있습니다.

Filter 커스터마이징

...

...

CtaView (버튼) 커스터마이징

2.21 버전 이상에서는 아래 방법보다는 Theme을 활용하는 방법을 권장합니다.

...

베이스 리워드 지급 안내 UI 커스터마이징

...

베이스 리워드 지급시 유저에게 제공되는 피드백을 커스터마이즈 할 보여지는 UI 를 수정할 수 있습니다.

...

DefaultFeedFeedbackHandler의 상속 클래스는 작성합니다. 그리고, FeedConfig의 feedFeedbackHandler에 작성한 클래스를 설정합니다.

Code Block
languagekotlin
public class 

...

YourFeedFeedbackHandler extends DefaultFeedFeedbackHandler {
   @NotNull
   public View getBaseRewardNotificationView(@NotNull Context context, int reward) {
      // 베이스 리워드 지급시 피드 상단에 보여지는 notification view 입니다.
   }

   public void onBridgePointBaseRewardReceived(@NotNull Context context, int reward) {
      // 베이스 리워드 지급시 브릿지 포인트 연동 중일 경우 호출되는 콜백입니다.
   }
}

FeedConfig을 초기화할 때, 이전 스텝에서 생성한 CustomFeedFeedbackHandler를 넘겨줍니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")

...


 

...

     .feedFeedbackHandler(

...

YourFeedFeedbackHandler.class)
      .build();

Pop 활성화

...

버튼

...

Pop 활성화 버튼은 버튼의 디자인은 아래 가이드에 따라 커스터마이징 가능합니다수정할 수 있습니다.

  • 활성화 버튼의 색상과 아이콘은 테마 적용을 통해 변경할 수 있습니다.

  • 활성화 버튼의 텍스트는 DefaultOptInAndShowPopButtonHandler를 상속받는 클래스를 생성하여 변경할 수 있습니다문구는 DefaultOptInAndShowPopButtonHandler의 상속 클래스에서 설정합니다. 상속 클래스를 작성하고 FeedConfig에 설정합니다.

    Code Block
    languagejava
    class 

...

  • YourOptInAndShowPopButtonHandler extends DefaultOptInAndShowPopButtonHandler {
        // 활성화 

...

  • 버튼에 보여지는 

...

  • 문구입니다.
        @Override
        public String getOptInAndShowPopButtonText(Context context) {
            return "YOUR_BUTTON_TEXT"
        }
    }

FeedConfig에 구현한 CustomOptInAndShowPopButtonHandler를 설정합니다.

  • Code Block
    languagejava
    final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
        

...

  •   

...

  • .optInAndShowPopButtonHandler(CustomOptInAndShowPopButtonHandler.class)
          .build();