Fullscreen Implementation Guide
How immersive mode works with the StreamLayer SDK and what to watch for when implementing fullscreen on Android.
Unlike iOS and Web, Android's native immersive mode does not prevent the StreamLayer SDK from rendering formats like sidebar, L-bar, or PIP. Android's "fullscreen" mode simply hides the system bars (status bar and navigation bar) — it does not take control of the view hierarchy or restrict how the app lays out its views.
This means most Android integrations work in fullscreen without any special handling. This guide covers the setup and the edge cases to watch for.
Why Android Is Different
On iOS, native fullscreen (AVPlayerViewController) takes over the display and prevents the host app from resizing the video. On Web, the Fullscreen API applies forced CSS constraints. Android has neither of these limitations.
Android immersive mode uses WindowInsetsControllerCompat to hide system bars:
// Standard Android immersive mode — this does NOT affect StreamLayer
val controller = WindowCompat.getInsetsController(window, window.decorView)
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPEAfter this call, the system bars are hidden but your Activity's view hierarchy is unchanged. The StreamLayerFragment and your PlayerView remain siblings in the same ConstraintLayout, and you can resize either one freely.
Standard Fullscreen Setup
Place the StreamLayerFragment alongside your player view in a ConstraintLayout, then enter immersive mode. The SDK's layout system works identically in both windowed and fullscreen states.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.host.app.PlayerView
android:id="@+id/playerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/streamLayerContainer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="@id/playerView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>When the SDK triggers a sidebar or L-bar format, it calls your layout listener to adjust the player view constraints. This works the same whether system bars are visible or hidden.
// Listen for layout changes and forward to SDK — works in both modes
binding.playerView.addOnLayoutChangeListener(layoutListener)See the Layout Guide for the full layout listener implementation.
Edge Cases to Watch For
Third-Party Players With Custom Fullscreen
Some third-party video player libraries implement their own fullscreen by launching a new Activity or Dialog. If the player does this, the StreamLayerFragment will not be part of that new Activity's view hierarchy, so SDK UI will not appear.
If you use a third-party player, verify that its fullscreen mode stays within the same Activity and view hierarchy. If it does not, you have two options: disable the player's built-in fullscreen and implement your own (using immersive mode as shown above), or re-add the StreamLayerFragment to the player's fullscreen Activity.
Multi-Window and Freeform Mode
On tablets and foldables, Android supports multi-window and freeform window modes. The StreamLayer SDK handles these correctly as long as the StreamLayerFragment has accurate layout dimensions. Call overlayHeightSpace to update the SDK when the window size changes:
// Update SDK when window size changes (multi-window, foldable unfold, etc.)
binding.playerView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
streamLayerFragment.overlayHeightSpace = binding.playerView.height
}Picture-in-Picture (System PIP)
Android's system PIP mode (enterPictureInPictureMode()) shrinks the entire Activity to a small floating window. The StreamLayer SDK should be hidden during system PIP because the window is too small for interactive content. Use the onPictureInPictureModeChanged callback to hide and restore the SDK:
override fun onPictureInPictureModeChanged(isInPipMode: Boolean) {
super.onPictureInPictureModeChanged(isInPipMode)
if (isInPipMode) {
// Hide StreamLayer UI during system PIP
binding.streamLayerContainer.visibility = View.GONE
} else {
binding.streamLayerContainer.visibility = View.VISIBLE
}
}Quick Reference
| Scenario | SDK Formats Work? | Notes |
|---|---|---|
| Immersive mode (system bars hidden) | Yes | Standard approach, no issues |
| Third-party player fullscreen (same Activity) | Yes | Verify player stays in your Activity |
| Third-party player fullscreen (new Activity) | No | Disable player's fullscreen, use immersive mode instead |
| System PIP mode | No | Window too small — hide SDK, restore on exit |
| Multi-window / freeform | Yes | Forward layout changes to SDK |
Related
- Layout Guide — StreamLayer Element positioning and orientation handling
- Integration Guide — Full SDK setup for Android
- Troubleshooting — Common integration issues and fixes
Updated 15 days ago
