Android PlayerView Fullscreen, Orientation Detection, and Overlay Click Handling (Kotlin)

Building a modern Android video player experience similar to YouTube requires several components working together:

  • Detecting screen orientation changes
  • Handling fullscreen transitions
  • Listening for device orientation events
  • Rotating views programmatically
  • Managing PlayerView overlay interactions
  • Supporting delayed orientation changes
  • Implementing ExoPlayer/Media3 fullscreen behavior

This guide covers the key concepts and Kotlin examples for creating a responsive Android video player.


Understanding Screen Orientation vs Device Orientation

Many Android developers confuse these concepts:

Screen Orientation

The current layout orientation used by Android:

val orientation = resources.configuration.orientation

when (orientation) {
    Configuration.ORIENTATION_PORTRAIT -> {
        // Portrait UI
    }

    Configuration.ORIENTATION_LANDSCAPE -> {
        // Landscape UI
    }
}

Device Orientation

The physical position of the device measured by sensors.

Examples:

  • Upright portrait
  • Upside-down portrait
  • Landscape left
  • Landscape right
  • Flat on a table

This is detected using sensors or an OrientationEventListener.


Listening for Device Orientation Changes

The simplest approach:

private lateinit var orientationListener: OrientationEventListener

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    orientationListener = object : OrientationEventListener(this) {
        override fun onOrientationChanged(orientation: Int) {

            when {
                orientation in 45..135 -> {
                    // Landscape right
                }

                orientation in 225..315 -> {
                    // Landscape left
                }

                orientation >= 315 || orientation <= 45 -> {
                    // Portrait
                }
            }
        }
    }
}

override fun onResume() {
    super.onResume()
    orientationListener.enable()
}

override fun onPause() {
    super.onPause()
    orientationListener.disable()
}

The orientation value ranges from:

0°   = Portrait
90°  = Landscape
180° = Reverse Portrait
270° = Reverse Landscape

Adding Delayed Orientation Changes

YouTube does not instantly rotate the UI the moment the sensor changes.

A delayed approach avoids accidental fullscreen transitions:

private val handler = Handler(Looper.getMainLooper())

private var orientationRunnable: Runnable? = null

private fun scheduleOrientationChange(action: () -> Unit) {

    orientationRunnable?.let {
        handler.removeCallbacks(it)
    }

    orientationRunnable = Runnable {
        action()
    }

    handler.postDelayed(
        orientationRunnable!!,
        500
    )
}

Usage:

scheduleOrientationChange {
    enterFullscreen()
}

This creates a smoother experience similar to YouTube.


Detecting Screen Orientation Changes

Inside an Activity:

override fun onConfigurationChanged(
    newConfig: Configuration
) {
    super.onConfigurationChanged(newConfig)

    when (newConfig.orientation) {
        Configuration.ORIENTATION_LANDSCAPE -> {
            enterFullscreen()
        }

        Configuration.ORIENTATION_PORTRAIT -> {
            exitFullscreen()
        }
    }
}

Manifest:

<activity
    android:name=".PlayerActivity"
    android:configChanges="orientation|screenSize" />

Fullscreen Implementation

Enter Fullscreen

private fun enterFullscreen() {

    requestedOrientation =
        ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE

    WindowCompat.setDecorFitsSystemWindows(
        window,
        false
    )

    WindowInsetsControllerCompat(
        window,
        window.decorView
    ).hide(WindowInsetsCompat.Type.systemBars())
}

Exit Fullscreen

private fun exitFullscreen() {

    requestedOrientation =
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

    WindowCompat.setDecorFitsSystemWindows(
        window,
        true
    )

    WindowInsetsControllerCompat(
        window,
        window.decorView
    ).show(WindowInsetsCompat.Type.systemBars())
}

Programmatically Rotating a View

Any view, including a CardView, can be rotated:

cardView.rotation = 90f

Animated rotation:

cardView.animate()
    .rotation(90f)
    .setDuration(300)
    .start()

PlayerView Overlay Click Handling

A common pattern is placing an overlay above the player.

Layout

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.media3.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <View
        android:id="@+id/playerOverlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

Click Listener

binding.playerOverlay.setOnClickListener {

    if (binding.playerView.isControllerFullyVisible) {
        binding.playerView.hideController()
    } else {
        binding.playerView.showController()
    }
}

This mimics YouTube’s tap-to-show-controls behavior.


YouTube-Like Fullscreen Behavior

YouTube generally follows this pattern:

Portrait

  • Video displayed inline
  • Comments visible below
  • Normal activity layout

Rotate to Landscape

  • Sensor detects orientation
  • Short delay applied
  • Video enters fullscreen
  • System bars hidden
  • Controller shown briefly

Rotate Back

  • Exit fullscreen
  • Restore portrait layout
  • Show system bars

Pseudo-flow:

OrientationEventListener
          ↓
    Delay 300-500ms
          ↓
Landscape?
     ↓
Enter Fullscreen
     ↓
Hide System Bars
     ↓
Show Controls

Recommended Modern Stack

For Android development in 2026:

  • Media3 (androidx.media3)
  • PlayerView
  • OrientationEventListener
  • WindowInsetsControllerCompat
  • ViewBinding
  • Lifecycle-aware player management

Avoid:

  • Deprecated Orientation Sensor APIs
  • Legacy ExoPlayer 2 packages when Media3 is available
  • Old fullscreen flags like FLAG_FULLSCREEN

Example Architecture

PlayerFragment
│
├── PlayerView
├── Overlay View
├── OrientationEventListener
├── Fullscreen Manager
└── Media3 ExoPlayer

This architecture provides behavior very close to YouTube’s fullscreen experience while remaining clean, maintainable, and compatible with modern Android development practices.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back