Engagement starter on Android
The Engagement Starter is a compact, self-contained widget that invites readers into the
conversation for a piece of content. It picks its own layout based on what the conversation
actually has to show:
| Variant | When it renders | What it shows |
|---|---|---|
| Default | No poll and no featured comment | Header, title, description and a call-to-action button |
| Editor's pick | The conversation has a pinned or picked comment | The featured comment with its author, like/dislike/reply row, and the call to action |
| Poll | The conversation has a poll and polls are enabled for the site | The poll question, its options, and (after voting) results |
A pinned comment takes precedence over an editor's pick, and a poll takes precedence over
both.
In the Android SDK the widget is named Conversation Starter
(VFConversationStarterFragment), which is the same widget as the web Engagement Starter.
Requires com.viafoura:android 2.1.5 or newer.
Behaviour worth knowing before you integrate
- It never creates a conversation. The widget reads the comment container without
creating it, so rendering the Engagement Starter on an article that has never been
commented on does not bring a conversation into existence. When the container does not
exist yet (a 404 from the container lookup), the default variant is shown. - It hides itself when there is nothing to say. If the conversation is hidden, or closed
with zero comments, and there is no poll, the widget hides its content and reports a
height of0. Size the host container off the layout callback rather than a fixed height. - The call to action adapts to the comment count. With at least
minimumCommentCount
comments the button shows the count; with zero comments it invites the first comment;
otherwise it drops the count. The default is
ConversationStarterViewModel.DEFAULT_MINIMUM_COMMENT_COUNT(5). - On the poll variant the call to action only appears once results are visible — that is,
after the reader votes or once the poll is closed. - The dislike button on the featured comment is only rendered when dislikes are enabled
for the site, and voting on a poll prompts login only when the site requires
authentication to vote. - Analytics are on by default. The widget logs its own load, view and click events with a
subtype ofdefault,editor_pickorpoll. The view event fires when the widget is
resumed and loaded. To honour a reader's consent choice, call
ViafouraSDK.setDataTrackingEnabled(false); nothing else needs to change.
Adding the widget
The widget is a fragment, created through a builder.
Java
VFArticleMetadata metadata = new VFArticleMetadata(
new URL("https://example.com/article"),
"Article title",
"Article subtitle",
new URL("https://example.com/thumbnail.jpg"));
VFSettings settings = new VFSettings(new VFColors(colorPrimary, colorPrimaryLight));
VFConversationStarterFragment starter =
new VFConversationStarterFragmentBuilder("YOUR_CONTAINER_ID", metadata, settings)
.title(null) // optional override for the default variant's title
.description(null) // optional override for its description
.minimumCommentCount(5) // ConversationStarterViewModel.DEFAULT_MINIMUM_COMMENT_COUNT
.syndicationKey(null)
.build();
starter.setTheme(VFTheme.light);
starter.setActionCallback(this);
starter.setLayoutCallback(this);
starter.setCustomUICallback(this);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.engagement_starter_container, starter)
.commit();Kotlin
val starter = VFConversationStarterFragmentBuilder(containerId, metadata, settings)
.minimumCommentCount(5)
.build()
.apply {
setActionCallback(this@ArticleActivity)
setLayoutCallback(this@ArticleActivity)
setCustomUICallback(this@ArticleActivity)
setTheme(VFTheme.light)
}
supportFragmentManager.beginTransaction()
.replace(R.id.engagement_starter_container, starter)
.commit()Call .sectionUUID(uuid) on the builder if the content lives in a section other than your
site's default; otherwise the site UUID is used.
Actions
Actions arrive through VFActionsInterface:
@Override
public void onNewAction(VFActionType actionType, VFActionData action) {
switch (actionType) {
case seeMoreCommentsPressed:
// Reader tapped the call to action — open your comments screen
break;
case writeNewCommentPressed:
// Reader tapped "Reply" on the featured comment;
// action.newCommentAction carries the parent content UUID
break;
case openProfilePressed:
// action.openProfileAction carries the author's user UUID
break;
case authPressed:
// Reader reacted or voted while logged out — start your login flow
break;
default:
break;
}
}Height
The widget reports its own height through VFLayoutInterface, in dp:
@Override
public void containerHeightUpdated(VFFragment fragment, String containerId, int height) {
ViewGroup.LayoutParams params = starterContainer.getLayoutParams();
params.height = (int) AndroidUtils.convertDpToPixel(height, this);
starterContainer.setLayoutParams(params);
}The height is 0 whenever the widget hides itself, so a container driven by this callback
collapses the widget without leaving a gap.
Refreshing
starter.reload(); // re-fetch the container, featured comment and poll
starter.reloadPoll(); // re-fetch only the poll, e.g. after a poll changes elsewhereStyling
Colours, fonts and theme come from the VFSettings you pass in, and setTheme(VFTheme)
switches the theme at runtime.
For finer control, VFCustomUIInterface hands you these views:
VFCustomViewType | View |
|---|---|
conversationStarterBackgroundView | The widget's root layout |
conversationStarterHeaderLabel | The small header above the title |
conversationStarterTitleLabel | The default variant's title |
conversationStarterDescriptionLabel | The default variant's description |
conversationStarterFeaturedCommentLabel | The featured comment's text |
conversationStarterActionButton | The call-to-action button |
@Override
public void customizeView(VFTheme theme, VFCustomViewType customViewType, View view) {
if (customViewType == VFCustomViewType.conversationStarterActionButton) {
view.setBackgroundResource(R.drawable.my_rounded_button);
}
}Updated about 7 hours ago
