Introduction
Download SDK and Sample App
Integrating with the SDK
Setup Smartfeed
RecycleView Integration
Step 1: Create OBSmartFeed
Step 2: Connect Your Adapter to OBSmartFeed
Step 3 (Optional): Implement Custom UI
OBSmartFeed Listener
OBSmartFeed Viewability
OBSmartFeed RTB Support
Outbrain Logo


Introduction

Important: Outbrain SDK version 3.0.0 which introduce Smartfeed for the first time, is currently in closed beta.

Outbrain Smartfeed is a brand new way for publishers to integrate Outbrain recommendations in their native app in a way that feels natural to their users (infinite scrolling at the end of the original article) and seamless for app developers to integrate.

See example of how Smartfeed works below:



Download SDK and Sample App

Sample App

Please download Smartfeed sample app with this download link.

Source Code

Please download the sample app source code with this download link. Please note this link is password protected, ask your TAM for more information.

SDK 3.0.0

The SDK (still closed beta) is available via this integration line in build.gradle

compile 'com.outbrain.obsdk:obsdk:3.0.0.beta4'


Integrating with the SDK

Smartfeed is an integral part of the SDK, therefore you must integrate and init the SDK according to the instructions in our main developers guide page.


Setup Smartfeed

Finally we get to the interesting part of this guide, here are the actual steps necessary for app developers to make use of Smartfeed in their application.

OBSmartFeed is the Class responsible for managing the Smartfeed. You should create an instance of OBSmartFeed in the relevant Activity where the original article is displayed.


Important: The `OBSmartFeed` should be an “instance variable” in the Activity since the instance has to be alive while the Activity is alive (in other words, if `OBSmartFeed` will be a local variable it will be collected by the Garbage Collector while the screen is still active).


RecycleView Integration


Step 1: Create OBSmartFeed

We recommend to setup OBSmartFeed in the Activity onCreate method, for example:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.obSmartFeed = new OBSmartFeed(getString(R.string.outbrain_sample_url), OUTBRAIN_WIDGET_ID, recyclerView, "CNN", R.drawable.cnn_logo, this);
    mAdapter.setOBSmartFeed(obSmartFeed); // connects RecycleView adapter to the OBSmartFeed instance
    this.obSmartFeed.setupInfiniteScroll();  // setup infinite scroll 
    ...
    ...
    // Your code is here
}


We initilize OBSmartFeed with:

1) baseURL – the current article URL

2) widgetID – an additional Outbrain widget ID — different from the primary widgetID (has to be configured to be of type “smartfeed”, please consult with you account manager for more details).

3) RecycleView – the recycle view instance.

4) Publisher name (String).

5) Publisher image (Int – resource id).

6) OBSmartFeedListener (usually the current Activity).


Please note: as the sample code above show, we have to implement `OBSmartFeedListener` methods in the Activity in order to receive the events of: clicks on recommendations in the feed and clicks on “Ad Choices” icon in case of recommendation of type OPA. Read more about OBSmartFeed Listener


An example of where we use publisher name and image




Connecting Adapter to OBSmartFeed

Please notice the line of code where we call:

mAdapter.setOBSmartFeed(obSmartFeed);

This is mandatory for the Adapter to have a reference to the OBSmartFeed instance since we have to call it at key Adapter methods (we’ll explain more below).


Setup infinite scroll

Please notice the line of code where we call:

this.obSmartFeed.setupInfiniteScroll();

This is mandatory for the “infinite scroll” behaviour to work as expected.


Step 2: Connect Your Adapter to OBSmartFeed

OBSmartFeed should be called from key methods in the RecycleView.Adapter.

The methods you should call OBSmartFeed are:

1)
public int getItemCount()

2)
public int getItemViewType(int position)

3)
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)

4)
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)



getItemCount

Smartfeed recommendations will be added to the collection view at the bottom. Therefore we need to implement the method as follows

public int getItemCount() {
    return ORIGINAL_RECYCLE_VIEW_SIZE + this.obSmartFeed.getSmartFeedItems().size();
}


getItemViewType

public int getItemViewType(int position) {
    switch (position) {
        case 0:
            return ARTICLE_HEADER_VIEW_TYPE;
        case 1:
            return TEXT_VIEW_TYPE;
        case 2:
            return TEXT_VIEW_TYPE;
        case 3:
            return TEXT_VIEW_TYPE;
        case 4:
            return OUTBRAIN_HEADER_VIEW_TYPE;
        default:
            return this.obSmartFeed.getItemViewType(position, ORIGINAL_RECYCLE_VIEW_SIZE);
    }
}


onCreateViewHolder

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View v;
    switch (viewType) {
        case TEXT_VIEW_TYPE:
            v = inflater.inflate(R.layout.article_text_row, parent, false);
            TextItemViewHolder tvh = new TextItemViewHolder(v);
            return tvh;
        case ARTICLE_HEADER_VIEW_TYPE:
            v = inflater.inflate(R.layout.article_header_row, parent, false);
            ImageItemViewHolder ivh = new ImageItemViewHolder(v);
            return ivh;
        case OUTBRAIN_HEADER_VIEW_TYPE:
            v = inflater.inflate(R.layout.outbrain_sfeed_header, parent, false);
            return new OutbrainHeaderViewHolder(v);
        default:
            return this.obSmartFeed.onCreateViewHolder(parent, viewType);
    }
}


onBindViewHolder

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    TextItemViewHolder tvh;

    switch (position) {
        case 0:
            break;
        case 1:
            tvh = (TextItemViewHolder)holder;
            tvh.textView.setText(tvh.textView.getContext().getResources().getString(R.string.article_txt_1));
            break;
        case 2:
            tvh = (TextItemViewHolder)holder;
            tvh.textView.setText(tvh.textView.getContext().getResources().getString(R.string.article_txt_2));
            break;
        case 3:
            // ...
            break;
        case 4:
            // ...
            break;
        default:
            this.obSmartFeed.onBindViewHolder(holder, position, ORIGINAL_RECYCLE_VIEW_SIZE);
    }


Step 3 (Optional): Implement Custom UI

By default, Smartfeed just works, “out of the box”, by implementing steps 1-2 Smartfeed will be available in the Activity you set it on. Nevertheless, if you’d like to customize the appearance of the “Smartfeed View” in the RecycleView, you can definitely do it.


The following cells can be customize by implementing their layout xml

1) outbrain_sfeed_horizontal_item.xml – to implement the UI for each View item in the horizontal carousel.

2) outbrain_sfeed_single_item.xml – to implement the UI for a “Single” Smartfeed View.




Customize Carousel View Item


Important: It will be very helpful to take an example from the Smartfeed sample app.

1) Create an xml file by the name outbrain_sfeed_horizontal_item.xml in res/layout folder.

2) Start with the outbrain_sfeed_horizontal_item.xml template file (ask your TAM for a download link).

3) Make sure to keep the same views with the same “+id/..” – you can change the following attributes: position, size, font, text size.


Customize Single View

1) Create an xml file by the name outbrain_sfeed_single_item.xml in res/layout folder.

2) Start with the outbrain_sfeed_single_item.xml template file (ask your TAM for a download link).

3) Make sure to keep the same views with the same “+id/..” – you can change the following attributes: position, size, font, text size.


OBSmartFeed Listener

Please note as the sample code above show, we have to set the OBSmartFeed Listener in order to handle clicks on recommendations in the feed.

public interface OBSmartFeedListener {
    void userTappedOnRecommendation(OBRecommendation rec);

    void userTappedOnAdChoicesIcon(String url);
}



An example for OBSmartFeed Listener implementation might be:


@Override
public void userTappedOnRecommendation(OBRecommendation rec) {
    Log.i(LOG_TAG, "userTappedOnRecommendation: " + rec.getContent());
    String url = Outbrain.getUrl(rec);
    CatalogUtils.openURLInBrowser(url, this);
}

@Override
public void userTappedOnAdChoicesIcon(String url) {
    Log.i(LOG_TAG, "userTappedOnAdChoicesIcon: " + url);
    CatalogUtils.openURLInBrowser(url, this);
}


Smartfeed Widget Viewability

According to our instructions regarding widget viewability – app developers should implement the text at the widget header with OBLabel and call:

Outbrain.registerOBTextView(outbrainHeaderVH.outbrainTextView, this.outbrainWidgetId, this.outbrainUrl);


See example for using OBTextView to display “Sponsored” in the sample app:




Smartfeed RTB Support

OBSmartFeed supports RTB “out of the box”, i.e. the displaying of the “Ad Choices” icon is done for you. All you, as the app developer, should do, is make sure to implement the click handling for the ad choices icon via OBSmartFeedListener. On click you should open the provided URL in a browser. See example code below:


@Override
public void userTappedOnAdChoicesIcon(String url) {
    Log.i(LOG_TAG, "userTappedOnAdChoicesIcon: " + url);
    CatalogUtils.openURLInBrowser(url, this);
}




According to our instructions regarding Outbrain widget labeling – app developers should implement a click handler on Outbrain logo in the following way:

outbrainHeaderVH.outbrainLogoButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String aboutOutbrainUrl = Outbrain.getOutbrainAboutURL(v.getContext());
        CatalogUtils.openURLInBrowser(aboutOutbrainUrl, v.getContext());
    }
});