Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 65 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Preface

This project showcases how to integrate Taboola's SDK on Android and use its HomePage capabilities.
This project showcases how to integrate Taboola's SDK on Android and use its HomePage capabilities.

### Initialization

Expand Down Expand Up @@ -38,13 +38,27 @@ The parameters you need to pass in are:

2. Next, it is advised to call `fetchContent` as soon as you can so that content will be loaded into the HomePage instance

homePage.fetchContent();
- Home page Swapping approach:
`homePage.fetchContent();`

- Home page Data API approach:
`homePage.fetchContent(object : TBLFetchContentCallback {
override fun onComplete(isHomePageEnabled: Boolean, homePageDataSource: TBLHomePageDataSource) {
// Save recommendations to your data structure
}
override fun onFailure(error: String) {
// Handle the failure
}
});
`

### Swap Articles

To swap articles with content from Taboola,
call the `shouldSwapItemInSection` function in your OnBind methd to get the swapped item's content.
It returns True if the item was swapped, False if it wasn't.
- Home page Swapping approach:

To swap articles with content from Taboola,
call the `shouldSwapItemInSection` function in your OnBind methd to get the swapped item's content.
It returns True if the item was swapped, False if it wasn't.


public boolean shouldSwapItemInSection(
Expand All @@ -56,20 +70,54 @@ It returns True if the item was swapped, False if it wasn't.
@Nullable final ImageView thumbnailView,
@Nullable AdditionalViews additionalViews)

The parameters you need to pass in are:
- linePosition: of the cell
- sectionName: representing section
- lineView: view of the cell
- titleView: UI element representing the title of the cell
- contentView: UI element representing the description of the cell
- thumbnailView: UI element representing the image of the cell
- additionalView(optional): UI element representing the all other view in the lineView which aren’t mandatory
The parameters you need to pass in are:
- linePosition: of the cell
- sectionName: representing section
- lineView: view of the cell
- titleView: UI element representing the title of the cell
- contentView: UI element representing the description of the cell
- thumbnailView: UI element representing the image of the cell
- additionalView(optional): UI element representing the all other view in the lineView which aren’t mandatory

- Home page Data API approach:

Invoke `shouldSwapItemInSectionDataApi` for every item in your list after receiving the
recommendations (and only if the home page is enabled).
Invoking this method for all of your items (including those that will not be swapped) is necessary
for Taboola to maintain an accurate map of sections and positions.
The boolean value returned by `shouldSwapItemInSectionDataApi` (true or false) indicates whether
the item should be swapped:
If `true`: Replace the current list item with the available item from Toboola's recommendations list.
If `false`: Invoke addClickUrlForDuplicationCheck to allow Taboola to track if this item is duplicated elsewhere on the homepage.

public boolean shouldSwapItemInSectionDataApi(
String sectionName,
int linePosition,
int sectionStartPosition)

The parameters you need to pass in are:
- sectionName: representing section
- linePosition: of the cell
- sectionStartPosition: position of the first item in the section

#### How does the swapping take place?
When you call `shouldSwapItemInSection`, Taboola verifies that this item is allowed to be swapped and validates the fields of the content, then performs a swap with a recommendation.
Taboola will handle the views the publisher desires to swap.
It will validate the fields of the content and the swapped content as well.
After a successful validation - Taboola will swap the publisher’s content with Taboola recommendations, and return a boolean that indicates if the swapping process did occur.

- Home page Swapping approach:

When you call `shouldSwapItemInSection`, Taboola verifies that this item is allowed to be swapped and validates the fields of the content, then performs a swap with a recommendation.
Taboola will handle the views the publisher desires to swap.
It will validate the fields of the content and the swapped content as well.
After a successful validation - Taboola will swap the publisher’s content with Taboola recommendations, and return a boolean that indicates if the swapping process did occur.

- Home page Data API approach:

After calling `shouldSwapItemInSectionDataApi`, you must report the result calling `reportSwapDataApi'

If swap succeeds: Pass `true` for `itemHasBeenSwapped`
`homePage.reportSwapDataApi(sectionName, position, true);`

If swap fails: Pass `false` for `itemHasBeenSwapped`
`homePage.reportSwapDataApi(sectionName, position, false);`

### Additional HomePage functionality

Expand Down
7 changes: 4 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ plugins {
}

android {
compileSdk 32
compileSdk 36

defaultConfig {
applicationId "com.taboola.hp4udemoapplication"
minSdk 21
targetSdk 32
targetSdk 36
versionCode 1
versionName "1.0"

Expand All @@ -35,6 +35,7 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
namespace 'com.taboola.hp4udemoapplication'
}

dependencies {
Expand All @@ -50,7 +51,7 @@ dependencies {
implementation 'androidx.core:core-splashscreen:1.0.0-rc01'
implementation 'com.squareup.picasso:picasso:2.8'
//Taboola SDK
implementation 'com.taboola:android-sdk:3.8.13'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanjacurcic-taboola - Notice that you changed the major version (from three to four). I would make sure nothing was impacted.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've already checked the entire app, everything seems fine.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanjacurcic-taboola - Remember you can only merge this once 4.0.17 has been released officially.

implementation 'com.taboola:android-sdk:4.0.17'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ArticleDiffCallback(
} else {
((oldItem as Article).title == (newItem as Article).title
&& oldItem.content == newItem.content
&& oldItem.imageUrl == newItem.imageUrl
&& oldItem.imageResourceId == newItem.imageResourceId
&& oldItem.url == newItem.url
&& oldItem.category == newItem.category)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.taboola.hp4udemoapplication.model.Header

class HomePageAdapter(
private var homePage: TBLHomePage?,
private val isHomePageDataApiMode: Boolean,
private val onItemClickListener: HomePageItemClickListener
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
Expand Down Expand Up @@ -47,7 +48,10 @@ class HomePageAdapter(
return mainItemViewHolder
}
DEFAULT_ARTICLE -> {
val viewHolder = HomePageItemViewHolder(view)
val viewHolder = when (isHomePageDataApiMode) {
true -> HomePageDataApiItemViewHolder(view)
false -> HomePageItemViewHolder(view)
}
view.setOnClickListener {
val url = (data[viewHolder.adapterPosition] as Article).url
onItemClickListener.onClick(url)
Expand All @@ -65,11 +69,15 @@ class HomePageAdapter(
(holder as MainHomePageItemViewHolder).onBind(data[position] as Article)
}
DEFAULT_ARTICLE -> if (data[position] is Article) {
(holder as HomePageItemViewHolder).onBind(
(holder as? HomePageItemViewHolder)?.onBind(
homePage,
position,
data[position] as Article
)

(holder as? HomePageDataApiItemViewHolder)?.onBind(
data[position] as Article
)
}
HEADER -> if (data[position] is Header) {
(holder as HeaderViewHolder).onBind(data[position] as Header)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.taboola.hp4udemoapplication.adapters.articles

import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
import com.taboola.hp4udemoapplication.R
import com.taboola.hp4udemoapplication.model.Article
import com.taboola.hp4udemoapplication.view.AnimatedBackgroundTextView

class HomePageDataApiItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

private val title: TextView?
get() = itemView.findViewById(R.id.title)

private val content: TextView?
get() = itemView.findViewById(R.id.content)

private val image: ImageView?
get() = itemView.findViewById(R.id.image)

private val animatedBackgroundTextView: AnimatedBackgroundTextView?
get() = itemView.findViewById(R.id.swapped_indication)

fun onBind(article: Article) {
animatedBackgroundTextView?.isVisible = article.isSwapped
title?.text = article.title
content?.text = article.content
if (article.isSwapped) {
Picasso.get().load(article.url).into(image)
} else {
Picasso.get().load(article.imageResourceId).into(image)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ class HomePageItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
itemView,
title,
content,
image,
null
image
)
if (swappedPerformed == null || !swappedPerformed) {
animatedBackgroundTextView?.visibility = View.GONE
title?.text = article.title
content?.text = article.content
if (article.imageUrl != 0) {
Picasso.get().load(article.imageUrl).into(image)
if (article.imageResourceId != 0) {
Picasso.get().load(article.imageResourceId).into(image)
}
} else {
animatedBackgroundTextView?.visibility = View.VISIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class MainHomePageItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemV
fun onBind(article: Article) {
title?.text = article.title
content?.text = article.content
if (article.imageUrl != 0) {
Picasso.get().load(article.imageUrl).into(image)
if (article.imageResourceId != 0) {
Picasso.get().load(article.imageResourceId).into(image)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package com.taboola.hp4udemoapplication.model
data class Article(
var title: String,
var content: String,
var imageUrl: Int,
var imageResourceId: Int,
var url: String,
var category: String,
var sectionName: String
) : BaseItem(ARTICLE_TYPE)
var sectionName: String,
var isSwapped: Boolean = false
) : BaseItem(ARTICLE_TYPE)
Loading