Custom AdChoices
GFP SDK provides two ways to customize the AdChoices area of native ads to match your app's design:
| Feature | Description | Use Case |
|---|---|---|
| Custom AdChoices Icon | Replace the default i or x icon with your desired icon | Unify the look and feel of content and ads in feed formats |
| Custom AdChoices Screen | Implement your own screen that appears when AdChoices is clicked | Provide a consistent user experience with your app's overall design |
Custom AdChoices Icon
In S2S native ads delivered through GFP, an i or x icon is displayed in the GfpAdChoicesView area. If you want to unify the look and feel of content and ads in feed formats, you can customize the AdChoices icon.
This is useful when you're using a ... icon in the top-right corner of content and want to use the same ... icon for ads.
XML Layout Configuration
When creating your native ad layout, add custom attributes to GfpAdChoicesView:
<com.naver.gfpsdk.GfpAdChoicesView
android:id="@+id/ad_choices_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:gfp__ad__ad_choices_drawable_dark="@drawable/YOUR_ICON_DRAWABLE_FOR_DARK_MODE"
app:gfp__ad__ad_choices_drawable_light="@drawable/YOUR_ICON_DRAWABLE_FOR_LIGHT_MODE" />
Attribute Description
- gfp__ad__ad_choices_drawable_dark: Icon drawable resource ID for dark mode
- gfp__ad__ad_choices_drawable_light: Icon drawable resource ID for light mode
If you're not using dark mode, it's recommended to set the same drawable resource ID for both attributes.
Custom AdChoices Screen
This feature has been supported since GFP SDK version 6.5.0. You can implement your own screen that appears when GfpAdChoicesView is clicked in S2S native ads.
- When using custom AdChoices, the default AdChoices icon will not be rendered within GfpAdChoicesView
- You must implement the AdChoices icon in your UI yourself
This is not supported for native ads from C2S ad providers like DFP, FAN, and InMobi.
1. Enable Custom AdChoices
When requesting native ads, set setEnableCustomAdChoices(true) when creating GfpNativeAdOptions and pass it to GfpAdLoader.
- Kotlin
- Java
val adLoader = GfpAdLoader.Builder(context, adParam)
.withAdListener(object: AdEventListener() {
// Handle ad events
})
.withNativeAd(
GfpNativeAdOptions.Builder()
.setEnableCustomAdChoices(true) // Enable custom AdChoices
.build()
) { nativeAd ->
// Handle native ad load completion
}
.build()
GfpAdLoader adLoader = new GfpAdLoader.Builder(context, adParam)
.withAdListener(new AdEventListener() {
// Handle ad events
})
.withNativeAd(
new GfpNativeAdOptions.Builder()
.setEnableCustomAdChoices(true) // Enable custom AdChoices
.build(),
nativeAd -> {
// Handle native ad load completion
}
)
.build();
2. Check AdChoices Data Type and Configure UI
After loading the native ad, check the type of GfpAdChoicesData and configure your custom UI accordingly.
GfpAdChoicesData Type Classification
| Type | Included Data | Purpose |
|---|---|---|
| AdMute | adMuteFeedbacks | Only ad mute functionality available |
| Privacy | privacyUrl | Only navigation to privacy policy URL available |
| OptOut | adMuteFeedbacks, privacyUrl | Both ad mute and privacy policy available |
Field Description
| Field | Description |
|---|---|
| adMuteFeedbacks | List of ad mute reasons (List of AdMuteFeedback objects) |
| privacyUrl | Privacy policy URL (landing page when privacy icon is clicked) |
- Kotlin
- Java
val adLoader = GfpAdLoader.Builder(context, adParam)
.withAdListener(object: AdEventListener() {
// Handle ad events
})
.withNativeAd(
GfpNativeAdOptions.Builder()
.setEnableCustomAdChoices(true)
.build()
) { nativeAd ->
val adChoicesData = nativeAd.adChoicesData
// Check if custom AdChoices is available
if (nativeAd.isCustomAdChoicesEnabled && adChoicesData != null) {
setupCustomAdChoices(adChoicesData)
} else {
hideCustomAdChoices()
}
}
.build()
private fun setupCustomAdChoices(adChoicesData: GfpAdChoicesData) {
// Show AdChoices button
adChoicesButton.visibility = View.VISIBLE
// Set click event
adChoicesButton.setOnClickListener {
when (adChoicesData) {
is GfpAdChoicesData.AdMute -> {
// Show ad mute feedback list
showMuteFeedbackDialog(adChoicesData.adMuteFeedbacks)
}
is GfpAdChoicesData.Privacy -> {
// Navigate to privacy policy page
openPrivacyUrl(adChoicesData.privacyUrl)
}
is GfpAdChoicesData.OptOut -> {
// Show both ad mute and privacy policy options
showOptOutDialog(adChoicesData.adMuteFeedbacks, adChoicesData.privacyUrl)
}
}
}
}
private fun hideCustomAdChoices() {
adChoicesButton.visibility = View.GONE
}
GfpAdLoader adLoader = new GfpAdLoader.Builder(context, adParam)
.withAdListener(new AdEventListener() {
// Handle ad events
})
.withNativeAd(
new GfpNativeAdOptions.Builder()
.setEnableCustomAdChoices(true)
.build(),
nativeAd -> {
GfpAdChoicesData adChoicesData = nativeAd.getAdChoicesData();
// Check if custom AdChoices is available
if (nativeAd.isCustomAdChoicesEnabled() && adChoicesData != null) {
setupCustomAdChoices(adChoicesData);
} else {
hideCustomAdChoices();
}
}
)
.build();
private void setupCustomAdChoices(GfpAdChoicesData adChoicesData) {
// Show AdChoices button
adChoicesButton.setVisibility(View.VISIBLE);
// Set click event
adChoicesButton.setOnClickListener(v -> {
if (adChoicesData instanceof GfpAdChoicesData.AdMute) {
// Show ad mute feedback list
showMuteFeedbackDialog(((GfpAdChoicesData.AdMute) adChoicesData).getAdMuteFeedbacks());
} else if (adChoicesData instanceof GfpAdChoicesData.Privacy) {
// Navigate to privacy policy page
openPrivacyUrl(((GfpAdChoicesData.Privacy) adChoicesData).getPrivacyUrl());
} else if (adChoicesData instanceof GfpAdChoicesData.OptOut) {
// Show both ad mute and privacy policy options
GfpAdChoicesData.OptOut optOut = (GfpAdChoicesData.OptOut) adChoicesData;
showOptOutDialog(optOut.getAdMuteFeedbacks(), optOut.getPrivacyUrl());
}
});
}
private void hideCustomAdChoices() {
adChoicesButton.setVisibility(View.GONE);
}
3. Handle Ad Mute
Here's how to handle when a user selects a specific mute reason.
Processing Steps
- Pass mute reason: Pass the selected AdMuteFeedback to the GfpNativeAd object
- Hide UI: Hide the ad in your preferred way
- Kotlin
- Java
private fun onMuteFeedbackSelected(adMuteFeedback: AdMuteFeedback) {
// 1. Pass mute reason to SDK
nativeAd.muteAd(adMuteFeedback)
// 2. Hide ad from UI
hideAdvertisement()
}
private fun hideAdvertisement() {
// Hide ad in your preferred way
// Example: remove ad view, delete item from list, etc.
}
private void onMuteFeedbackSelected(AdMuteFeedback adMuteFeedback) {
// 1. Pass mute reason to SDK
nativeAd.muteAd(adMuteFeedback);
// 2. Hide ad from UI
hideAdvertisement();
}
private void hideAdvertisement() {
// Hide ad in your preferred way
// Example: remove ad view, delete item from list, etc.
}
The mute functionality only works when setEnableCustomAdChoices(true) is set.
4. Handle Privacy Policy URL
Here's how to handle navigation to the privacy policy URL when the Privacy icon is clicked.
- Kotlin
- Java
private fun openPrivacyUrl(privacyUrl: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(privacyUrl))
context.startActivity(intent)
}
private void openPrivacyUrl(String privacyUrl) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyUrl));
context.startActivity(intent);
}