Focus play/pause button when player controls open

This commit is contained in:
2026-04-12 18:39:57 +02:00
parent 360cd51e23
commit 16839942b1
2 changed files with 34 additions and 6 deletions

View File

@@ -48,6 +48,29 @@ class TvPlayerControlsOverlayTest {
@get:Rule @get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>() val composeRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun requestingControlsFocus_focusesPlayPauseInsteadOfSeekBar() {
composeRule.setContent {
AppTheme {
OverlayHost(
uiState = samplePlayerState(),
requestFocus = true
)
}
}
composeRule.waitForIdle()
composeRule.onNodeWithTag(TvPlayerPlayPauseButtonTag).assertIsFocused()
composeRule.onNodeWithTag(TvPlayerSeekBarTag)
.assert(
SemanticsMatcher.expectValue(
SemanticsProperties.Focused,
false
)
)
}
@Test @Test
fun downFromSeekBar_movesFocusToControlButtonsBeforePlaylist() { fun downFromSeekBar_movesFocusToControlButtonsBeforePlaylist() {
composeRule.setContent { composeRule.setContent {
@@ -433,7 +456,8 @@ class TvPlayerControlsOverlayTest {
@Composable @Composable
private fun OverlayHost( private fun OverlayHost(
uiState: PlayerUiState, uiState: PlayerUiState,
initiallyExpanded: Boolean = false initiallyExpanded: Boolean = false,
requestFocus: Boolean = false
) { ) {
var isPlaylistExpanded by remember { mutableStateOf(initiallyExpanded) } var isPlaylistExpanded by remember { mutableStateOf(initiallyExpanded) }
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
@@ -441,6 +465,12 @@ private fun OverlayHost(
val audioButtonFocusRequester = remember { FocusRequester() } val audioButtonFocusRequester = remember { FocusRequester() }
val subtitlesButtonFocusRequester = remember { FocusRequester() } val subtitlesButtonFocusRequester = remember { FocusRequester() }
LaunchedEffect(requestFocus) {
if (requestFocus) {
focusRequester.requestFocus()
}
}
Box(modifier = Modifier.size(width = 960.dp, height = 540.dp)) { Box(modifier = Modifier.size(width = 960.dp, height = 540.dp)) {
TvPlayerControlsOverlay( TvPlayerControlsOverlay(
uiState = uiState, uiState = uiState,

View File

@@ -186,7 +186,6 @@ private fun TvPlayerBottomSection(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val scheme = MaterialTheme.colorScheme val scheme = MaterialTheme.colorScheme
val playPauseFocusRequester = remember { FocusRequester() }
val playlistFocusRequester = remember { FocusRequester() } val playlistFocusRequester = remember { FocusRequester() }
var wasPlaylistExpanded by remember { mutableStateOf(isPlaylistExpanded) } var wasPlaylistExpanded by remember { mutableStateOf(isPlaylistExpanded) }
@@ -194,7 +193,7 @@ private fun TvPlayerBottomSection(
if (isPlaylistExpanded && uiState.queue.isNotEmpty()) { if (isPlaylistExpanded && uiState.queue.isNotEmpty()) {
playlistFocusRequester.requestFocus() playlistFocusRequester.requestFocus()
} else if (wasPlaylistExpanded) { } else if (wasPlaylistExpanded) {
playPauseFocusRequester.requestFocus() focusRequester.requestFocus()
} }
wasPlaylistExpanded = isPlaylistExpanded wasPlaylistExpanded = isPlaylistExpanded
} }
@@ -255,10 +254,9 @@ private fun TvPlayerBottomSection(
onSeekRelative = onSeekRelative, onSeekRelative = onSeekRelative,
togglePlayState = onPlayPause, togglePlayState = onPlayPause,
onMoveDown = { onMoveDown = {
playPauseFocusRequester.requestFocus() focusRequester.requestFocus()
true true
}, },
focusRequester = focusRequester,
modifier = Modifier.testTag(TvPlayerSeekBarTag) modifier = Modifier.testTag(TvPlayerSeekBarTag)
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@@ -292,7 +290,7 @@ private fun TvPlayerBottomSection(
onClick = onPlayPause, onClick = onPlayPause,
size = 72, size = 72,
modifier = expandPlaylistModifier modifier = expandPlaylistModifier
.focusRequester(playPauseFocusRequester) .focusRequester(focusRequester)
.testTag(TvPlayerPlayPauseButtonTag) .testTag(TvPlayerPlayPauseButtonTag)
) )
TvIconButton( TvIconButton(