ui_controller_view.xml
Overview
`ui_controller_view.xml` is an Android layout file that defines the user interface for a custom video player controller view within the Tubi TV app. It provides an interactive control panel overlay for video playback, including features such as play/pause toggling, seek bar, rewind/forward buttons, subtitle toggling, and ad-related UI elements.
The file uses Android Data Binding to bind UI components directly to a `UserController` view model ([com.tubitv.media.bindings.UserController](/projects/288/68379)), enabling reactive updates of UI elements based on the player state. It leverages ConstraintLayout for flexible positioning and responsiveness and includes custom views such as `VaudTextView`, `StateImageButton`, and `TubiLoadingView` to match Tubi's branding and UX requirements.
Detailed Components and Bindings
Root Elements
<layout>: Root element enabling Android Data Binding in this XML file.<data>: Declares imports and variables for data binding.Imports:
com.google.android.exoplayer2.ExoPlayer(used for referencing player states)android.view.View(for visibility constants)
Variable:
controllerof type com.tubitv.media.bindings.UserController — the binding view model providing video playback state and control methods.
<FrameLayout>: Root container holding the entire controller UI, matching the parent size.
1. Controller Panel (ConstraintLayout with id controller_panel)
This panel overlays the video content to show playback controls. It is initially hidden (`android:visibility="gone"`), presumably made visible by the app when the user interacts with the video.
Background: Semi-transparent overlay color (
@color/tubi_tv_player_controls_overlay)Layout: Uses
ConstraintLayoutto align controls responsively.
Key UI Elements within Controller Panel:
Component | Description | Binding / Functionality |
|---|---|---|
**`VaudTextView` (id: `view_tubi_controller_title`)** | Shows video title | Bound to `controller.videoName` |
**`StateImageButton` (id: `view_tubi_controller_subtitles_ib`)** | Toggles subtitles on/off | Visibility depends on `controller.videoHasSubtitle && !controller.isCurrentAd`. |
**`` (id: `view_tubi_controller_ad_description`)** | Includes ad description layout (`view_tubi_ad_learn_more`) | Visible only during ads (`controller.isCurrentAd`). |
**`ImageButton` (id: `view_tubi_controller_rewind_ib`)** | Rewind 15 seconds | Click triggers `controller.seekBy(-1500 * 10)` (milliseconds). |
**`StateImageButton` (id: `view_tubi_controller_play_toggle_ib`)** | Play/Pause toggle button | Click toggles play state via `controller.triggerPlayOrPause(!controller.isVideoPlayWhenReady)`. |
**`ImageButton` (id: `view_tubi_controller_forward_ib`)** | Forward 15 seconds | Click triggers `controller.seekBy(1500 * 10)`. |
**`VaudTextView` (id: `view_tubi_controller_elapsed_time`)** | Shows current playback time | Bound to `controller.videoPositionInString` with default fallback string. |
**`SeekBar` (id: `view_tubi_controller_seek_bar`)** | Video progress bar | Max bound to video duration. |
**`VaudTextView` (id: `view_tubi_controller_remaining_time`)** | Shows remaining playback time | Bound to `controller.videoRemainInString` with default fallback string. |
Layout Guidelines
Several vertical and horizontal `Guideline`s are defined for consistent alignment and margins:
Top, bottom, left, right edges
Seek bar left and right boundaries
These guidelines help position UI elements responsively on different screen sizes.
2. Loading Indicator (TubiLoadingView with id view_tubi_controller_loading)
Positioned centered on screen.
Shows a loading spinner when the player is buffering or idle, based on:
controller.playerPlaybackState == ExoPlayer.STATE_BUFFERING || controller.playerPlaybackState == ExoPlayer.STATE_IDLE
Variables and Their Roles (from UserController)
Variable / Property | Purpose / Description |
|---|---|
`videoName` | Current video's title string |
`videoHasSubtitle` | Boolean indicating if video has subtitles |
`isSubtitleEnabled` | Boolean subtitle toggle state |
`isCurrentAd` | Boolean indicating if the current media is an ad |
`isVideoPlayWhenReady` | Boolean indicating if video is playing |
`videoPositionInString` | Current playback time as formatted string (e.g., "00:01:23") |
`videoRemainInString` | Remaining time as formatted string |
`videoDuration` | Total duration of the video in milliseconds |
`videoCurrentTime` | Current playback position in milliseconds |
`videoBufferedPosition` | Buffered position in milliseconds |
`playerPlaybackState` | Current ExoPlayer playback state (buffering, idle, ready, etc.) |
Important Implementation Details
Data Binding: The layout uses Data Binding extensively. UI components reactively update and trigger actions on user interaction by binding to the
UserControllerproperties and methods.Custom Views:
VaudTextViewandStateImageButtonare specialized views providing custom fonts, styling, and toggle state management.Ad Handling: UI elements adjust visibility and interactivity based on whether an ad is playing (
isCurrentAd), e.g., disabling seek bar, hiding rewind/forward buttons, showing ad description.Seek Bar Behavior: The seek bar listens for user interactions and calls back to the controller for handling seeking logic, including disabling seeking during ads.
Play/Pause and Subtitle Toggle: The play toggle and subtitle button reflect state visually and invoke controller methods to trigger playback or subtitle state changes.
ConstraintLayout Guidelines: Use of multiple guidelines ensures consistent spacing and alignment of controls independent of device size.
Interaction with Other System Components
UserController(ViewModel / Binding Class): This layout is tightly coupled to theUserControllerclass, which manages video playback state, user interactions, and business logic for controlling the player.ExoPlayer: The playback states and controls are based on integration with ExoPlayer, a popular Android media player library.
Included Layout
view_tubi_ad_learn_more: This layout is included to display ad-related content when an ad is playing.Custom UI Components: The layout depends on Tubi's custom UI components (
VaudTextView,StateImageButton,TubiLoadingView) which provide branded visuals and behaviors.App Resources: Uses app-defined colors, dimensions, and drawable selectors for consistent appearance matching the Tubi TV brand.
Usage Example
Assuming this layout is inflated within an activity or fragment, the following is an example of how it might be used:
// Inflate layout with Data Binding
val binding: UiControllerViewBinding = DataBindingUtil.inflate(
layoutInflater, R.layout.ui_controller_view, parent, false
)
// Create or obtain UserController instance managing playback
val userController = UserController(player, ...)
// Bind controller to layout
binding.controller = userController
// Show controller panel when needed
binding.controllerPanel.visibility = View.VISIBLE
// The UI now reflects the current player state and reacts to user input
Mermaid Diagram: Component Structure and Interactions
classDiagram
class UserController {
+String videoName
+boolean videoHasSubtitle
+boolean isSubtitleEnabled
+boolean isCurrentAd
+boolean isVideoPlayWhenReady
+String videoPositionInString
+String videoRemainInString
+long videoDuration
+long videoCurrentTime
+long videoBufferedPosition
+int playerPlaybackState
+void triggerPlayOrPause(boolean play)
+void triggerSubtitlesToggle(boolean enable)
+void seekBy(int milliseconds)
+void onProgressChanged(SeekBar, int, boolean)
+void onStartTrackingTouch(SeekBar)
+void onStopTrackingTouch(SeekBar)
}
class ui_controller_view {
+VaudTextView view_tubi_controller_title
+StateImageButton view_tubi_controller_subtitles_ib
+ViewGroup view_tubi_controller_ad_description
+ImageButton view_tubi_controller_rewind_ib
+StateImageButton view_tubi_controller_play_toggle_ib
+ImageButton view_tubi_controller_forward_ib
+VaudTextView view_tubi_controller_elapsed_time
+SeekBar view_tubi_controller_seek_bar
+VaudTextView view_tubi_controller_remaining_time
+TubiLoadingView view_tubi_controller_loading
}
ui_controller_view --> UserController : binds to
Summary
`ui_controller_view.xml` defines a rich, data-bound video playback controller UI for the Tubi TV app. By leveraging Android Data Binding and ConstraintLayout, it provides a responsive, interactive overlay with play controls, time displays, subtitle toggling, and ad awareness. The layout communicates closely with the `UserController` view model to reflect real-time playback state and handle user interactions seamlessly.
This modular design allows the controller UI to be reused and easily maintained, while providing users with intuitive and responsive video controls consistent with the Tubi brand.