Configure Video Feed View
FwVideoFeedView is a custom view that displays video thumbnails in a scrollable feed. Users can tap on any thumbnail to launch the fullscreen video player. The feed supports multiple layout types (horizontal, vertical, grid) and can display content from various sources.
Integration
Add to Layout
Add FwVideoFeedView to your layout XML file:
<com.firework.videofeed.FwVideoFeedView
android:id="@+id/videoFeedView"
android:layout_width="match_parent"
android:layout_height="match_parent" />Initialize
Initialize the feed view by calling init():
class MainActivity : AppCompatActivity() {
private lateinit var videoFeedView: FwVideoFeedView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
videoFeedView = findViewById(R.id.videoFeedView)
// Simple initialization with defaults
videoFeedView.init()
}
override fun onDestroy() {
videoFeedView.destroy()
super.onDestroy()
}
}Initialize with ViewOptions
Provide ViewOptions to customize the feed:
val viewOptions = viewOptions {
baseOptions {
feedResource(FeedResource.Discovery)
}
layoutOptions {
feedLayout(FeedLayout.GRID)
columnCount(3)
itemSpacing(8.dpToPx())
}
}
videoFeedView.init(viewOptions)Configuration Options
Feed Source (BaseOption)
Configure the content source for the feed. See Feed Sources for detailed information on each type.
viewOptions {
baseOptions {
// Discovery feed
feedResource(FeedResource.Discovery)
// Or Channel feed
feedResource(FeedResource.Channel(channelId = "your_encoded_channel_id"))
// Or Playlist feed
feedResource(
FeedResource.Playlist(
channelId = "your_encoded_channel_id",
playlistId = "your_encoded_playlist_id"
)
)
// Or Single content
feedResource(FeedResource.SingleContent(contentId = "your_encoded_content_id"))
// Or SKU-based feed
feedResource(
FeedResource.Sku(
channelId = "your_encoded_channel_id",
productIds = listOf("sku1", "sku2")
)
)
}
}For more feed types (HashtagPlaylist, DynamicContent, ShareUrl), see BaseOption Configuration.
Layout Configuration (LayoutOption)
Control the visual layout and appearance of the video feed.
Feed Layout Types
viewOptions {
layoutOptions {
// Horizontal scrolling row (default)
feedLayout(FeedLayout.HORIZONTAL)
// Or vertical scrolling column
feedLayout(FeedLayout.VERTICAL)
// Or multi-column grid
feedLayout(FeedLayout.GRID)
columnCount(3) // Only for grid layout
}
}Spacing and Appearance
viewOptions {
layoutOptions {
// Item spacing
itemSpacing(12.dpToPx()) // Space between items
// Background color
backgroundColor(Color.parseColor("#F5F5F5"))
// Rounded corners
roundedCorner(true)
roundedCornerRadius(12.dpToPx())
// Play icon
showPlayIcon(true)
playIconWidth(32.dpToPx())
// Aspect ratio
aspectRatio(9.0 / 16.0) // 9:16 ratio
}
}Title Position
viewOptions {
layoutOptions {
// Title overlays thumbnail (default)
feedTitlePosition(FeedTitlePosition.NESTED)
// Or title appears below thumbnail
feedTitlePosition(FeedTitlePosition.STACKED)
}
}For complete layout options, see LayoutOption Configuration.
Title Configuration (TitleOption)
Customize the appearance of feed titles.
viewOptions {
titleOptions {
// Visibility
showFeedTitle(true)
// Text styling
feedTitleTextColor(Color.WHITE)
feedTitleTextSize(18.spToPx())
feedTitleTextNumberOfLines(2)
feedTitleTextPadding(12.dpToPx())
// Background
feedTitleBackgroundColor(Color.parseColor("#80000000"))
// Custom font
feedTitleTextTypeface(
ResourcesCompat.getFont(context, R.font.custom_font)
)
}
}Gradient Background
viewOptions {
titleOptions {
feedTitleBackgroundDrawable(
GradientDrawable().apply {
colors = intArrayOf(
Color.parseColor("#667eea"),
Color.parseColor("#764ba2")
)
gradientType = GradientDrawable.LINEAR_GRADIENT
orientation = GradientDrawable.Orientation.TOP_BOTTOM
}
)
}
}For complete title options, see TitleOption Configuration.
Player Configuration (PlayerOption)
Configure the fullscreen video player that opens when users tap on video thumbnails.
viewOptions {
playerOptions {
// Autoplay first visible video in feed
autoplay(true)
// Player display mode
playerMode(PlayerMode.FIT_MODE) // or FULL_BLEED_MODE
// Auto-play next video when current ends
autoPlayOnComplete(true)
// UI elements
showShareButton(true)
showMuteButton(true)
showFireworkLogo(false)
// Picture-in-Picture
enablePipMode(true)
}
}For complete player configuration options, see Video Player Configuration.
CTA Configuration (CtaOption)
Configure Call-to-Action button behavior.
viewOptions {
ctaOptions {
// CTA visibility delay
ctaDelay(CtaDelay(3.0f, CtaDelayUnit.SECONDS))
// Or use percentage
ctaDelay(CtaDelay(0.5f, CtaDelayUnit.PERCENTAGE))
// CTA highlight delay
ctaHighlightDelay(CtaDelay(2.0f, CtaDelayUnit.SECONDS))
}
}Delay Units:
CtaDelayUnit.SECONDS- Delay in seconds (0.0 - 10.0, default: 3)CtaDelayUnit.PERCENTAGE- Percentage of video duration (0.0 - 1.0, default: 0.2)
For CTA handling, see Shopping Integration.
Ad Badge Configuration (AdBadgeOption)
Customize the ad badge appearance on sponsored content.
viewOptions {
adBadgeOptions {
// Visibility
adBadgeIsHidden(false)
adBadgeShowOnThumbnails(true)
// Appearance
adBadgeBackColor(Color.parseColor("#FFFECD"))
adBadgeTextColor(Color.BLACK)
// Label text
adBadgeLabel(AdBadgeTextType.SPONSORED) // or AdBadgeTextType.AD
// Custom font
adBadgeTypeface(ResourcesCompat.getFont(context, R.font.custom_font))
}
}Chat Configuration (ChatOption)
Configure livestream chat appearance.
viewOptions {
chatOptions {
// Chat text color
chatTextColor(Color.WHITE)
// Chat text shadow
chatTextShadowColor(Color.BLACK)
chatTextShadowOffsetX(2f)
chatTextShadowOffsetY(2f)
chatTextShadowRadius(4f)
}
}Feed Refresh
Manually refresh the feed to reload content:
videoFeedView.refresh()Example with SwipeRefreshLayout:
swipeRefreshLayout.setOnRefreshListener {
videoFeedView.refresh()
swipeRefreshLayout.isRefreshing = false
}Feed State Monitoring
Feed View State Listener
Monitor feed loading states and respond to state changes:
videoFeedView.setOnFeedViewStateListener { feedViewState ->
when (feedViewState) {
is FeedViewState.Loading -> {
// The feed is currently loading content
}
is FeedViewState.LoadData -> {
// Data has been successfully loaded and is available
}
is FeedViewState.EmptyFeed -> {
// The feed has no content to display
}
is FeedViewState.EndOfFeed -> {
// User has reached the end of available content
}
is FeedViewState.Error -> {
// An error occurred while loading feed content
}
}
}Feed View States:
Loading- Feed is currently loading contentLoadData- Data has been successfully loadedEmptyFeed- Feed has no content to displayEndOfFeed- End of available content reachedError- Error occurred with message
Error Listener
Handle errors during feed operations:
videoFeedView.setOnErrorListener { error ->
when (error) {
is SdkLevelError.SdkNotInitialized -> {
// SDK not initialized
showError("Please initialize Firework SDK first")
}
is VideoFeedError.LoadingFailed -> {
// Feed loading failed
showError("Failed to load video feed")
}
is NetworkError -> {
// Network error
showError("Network error. Please check your connection")
}
is AdsError -> {
// Ad-related error
Log.e("VideoFeed", "Ad error: ${error::class.simpleName}")
}
is LivestreamError -> {
// Livestream error
Log.e("VideoFeed", "Livestream error: ${error::class.simpleName}")
}
else -> {
showError("An error occurred: ${error::class.simpleName}")
}
}
}Error Types:
SdkLevelError.SdkNotInitialized- SDK not initializedVideoFeedError.LoadingFailed- Feed loading failedAdsError- Ad-related errors (VideoLoadFailed, PlaybackFailed, ImaAdFailed)LivestreamError- Livestream errors (MissingLivestreamInitializer, EngineFailed)ShareContentError- Share errors (EmptyShareUrl, SharingFailed)NetworkError- Network-related errorsPlayerError- Video playback errors
Feed Item Click Listener
Track when users tap on feed items:
videoFeedView.setOnFeedItemClickListener { feedItem ->
// Log analytics
Log.d("VideoFeed", "Video clicked: ${feedItem.title}")
// Access video information
val videoId = feedItem.id
val title = feedItem.title
val index = feedItem.indexInTheList
val duration = feedItem.duration
val videoInfo = feedItem.videoInfo
}FeedItem Properties:
id- Video content IDtitle- Video titleindexInTheList- Position in feedduration- Video duration in millisecondsvideoInfo- Detailed video information
Lifecycle Management
Destroy in Activity
Call destroy() when the feed view is no longer needed:
class VideoFeedActivity : AppCompatActivity() {
private lateinit var videoFeedView: FwVideoFeedView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_video_feed)
videoFeedView = findViewById(R.id.videoFeedView)
videoFeedView.init()
}
override fun onDestroy() {
videoFeedView.destroy()
super.onDestroy()
}
}Destroy in Fragment
In fragments, call destroy() in onDestroyView():
class VideoFeedFragment : Fragment() {
private var _binding: FragmentVideoFeedBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentVideoFeedBinding.bind(view)
binding.videoFeedView.init()
}
override fun onDestroyView() {
binding.videoFeedView.destroy()
super.onDestroyView()
_binding = null
}
}Complete Configuration Examples
Grid Layout Feed
class GridFeedActivity : AppCompatActivity() {
private lateinit var videoFeedView: FwVideoFeedView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_grid_feed)
videoFeedView = findViewById(R.id.videoFeedView)
val viewOptions = viewOptions {
baseOptions {
feedResource(FeedResource.Discovery)
}
layoutOptions {
feedLayout(FeedLayout.GRID)
columnCount(3)
itemSpacing(8.dpToPx())
roundedCorner(true)
roundedCornerRadius(12.dpToPx())
backgroundColor(Color.parseColor("#F8F9FA"))
showPlayIcon(true)
}
titleOptions {
showFeedTitle(true)
feedTitleTextColor(Color.WHITE)
feedTitleBackgroundColor(Color.parseColor("#80000000"))
feedTitleTextSize(14.spToPx())
feedTitleTextNumberOfLines(2)
}
playerOptions {
autoplay(false)
showShareButton(true)
enablePipMode(true)
}
}
videoFeedView.init(viewOptions)
}
override fun onDestroy() {
videoFeedView.destroy()
super.onDestroy()
}
}Horizontal Story Feed
class StoryFeedActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_story_feed)
val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
val viewOptions = viewOptions {
baseOptions {
feedResource(FeedResource.Channel(channelId = "your_channel_id"))
}
layoutOptions {
feedLayout(FeedLayout.HORIZONTAL)
itemSpacing(16.dpToPx())
roundedCorner(true)
roundedCornerRadius(12.dpToPx())
showPlayIcon(false) // No play icon for story style
aspectRatio(9.0 / 16.0)
}
titleOptions {
showFeedTitle(false)
}
playerOptions {
autoplay(false)
scrollingOrientation(ScrollingOrientation.VERTICAL)
}
}
videoFeedView.init(viewOptions)
}
}Product Video Gallery
class ProductGalleryActivity : AppCompatActivity() {
private fun loadProductVideos(productSku: String) {
val videoFeedView = findViewById<FwVideoFeedView>(R.id.productVideos)
// Set up error listener
videoFeedView.setOnErrorListener { error ->
Toast.makeText(this, "Error: ${error::class.simpleName}", Toast.LENGTH_SHORT).show()
}
// Set up state listener
videoFeedView.setOnFeedViewStateListener { state ->
when (state) {
is FeedViewState.Loading -> {
progressBar.isVisible = true
}
is FeedViewState.LoadData -> {
progressBar.isVisible = false
}
is FeedViewState.EmptyFeed -> {
progressBar.isVisible = false
emptyView.isVisible = true
}
else -> {}
}
}
val viewOptions = viewOptions {
baseOptions {
feedResource(
FeedResource.Sku(
channelId = "your_channel_id",
productIds = listOf(productSku)
)
)
}
layoutOptions {
feedLayout(FeedLayout.GRID)
columnCount(2)
itemSpacing(8.dpToPx())
roundedCorner(true)
showPlayIcon(true)
}
playerOptions {
autoplay(false)
showShareButton(true)
}
}
videoFeedView.init(viewOptions)
}
}Important Notes
Always call
init()before the feed view can display contentThe SDK must be initialized (via
FireworkSdk.init()) before callinginit()on the feed viewAlways call
destroy()when the feed view is no longer needed to free resourcesViewOptions provided to
init()allow complete customization of the feedFor grid layout,
columnCountdetermines the number of columnsAutoplay on thumbnails can impact battery and data usage
Use
dpToPx()for density-independent pixel valuesUse
spToPx()for text size values
See Also
Feed Sources - Learn about different content sources
ViewOptions Configuration - Complete configuration system
BaseOption - Feed source configuration
LayoutOption - Detailed layout customization
TitleOption - Title styling options
Video Player Configuration - Player configuration and features
Shopping Integration - CTA and shopping features
Widgets Overview - All available widgets
Last updated