Omkar Amberkar
12/17/2023, 4:56 PMchild box of parent column 2
to receive focus first before showing the collapsed state os the view. but in my case it just skips setting the focus there first and then showing the collapsed state. 🧵Omkar Amberkar
12/17/2023, 4:56 PMOmkar Amberkar
12/17/2023, 4:57 PMAnimatedVisibility(
visible = isVisible && menuState == MenuState.Collapsed,
modifier = modifier
.padding(bottom = minimizedHeightDp)
.align(Alignment.BottomCenter)
.fillMaxWidth()
.height(controlsHeightDp),
enter = fadeIn(),
exit = fadeOut()
) {
LogCompositions(message = "TvMenuOverlay Controls AnimatedVisibility Scope")
Column(
modifier = Modifier
.fillMaxSize()
.background(PlayerMenuComponentTokens.Color.Bg.Container.normal)
.ifElse(
{ isControlsRegionFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onFocusChanged {
if (it.hasFocus) {
Logger.d("TEST", "OverlaysState.Collapsed")
updateOverlaysState(OverlaysState.MetadataWithCollapsedMenu)
}
isControlsRegionFocused.value = it.hasFocus
}
) {
LogCompositions(message = "TvMenuOverlay Controls Scope")
Text(
text = "Parent Column 1",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
Row(
modifier = Modifier
.padding(
top = PlayerMenuComponentTokens.Padding.Top.Container.normal,
bottom = PlayerMenuComponentTokens.Spacing.btwnButtonsScrubber,
start = PlayerMenuComponentTokens.Padding.LR.Container.normal,
end = PlayerMenuComponentTokens.Padding.LR.Container.normal
)
.fillMaxWidth()
.height(ButtonComponentTokens.Height.normal)
.ifElse(
{ isButtonsRowFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onFocusChanged { isButtonsRowFocused.value = it.isFocused }
.focusRequester(buttonsRowFocusRequester)
.focusProperties {
up = FocusRequester.Cancel
down = FocusRequester.Default
left = FocusRequester.Cancel
right = FocusRequester.Cancel
}
.focusable()
) {
Text(
text = "Child Row of Parent Column 1",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
LogCompositions(message = "TvMenuOverlay Buttons Scope")
}
Box(
modifier = Modifier
.padding(
start = PlayerMenuComponentTokens.Padding.LR.Container.normal,
end = PlayerMenuComponentTokens.Padding.LR.Container.normal
)
.fillMaxWidth()
.height(PlaybackScrubberComponentTokens.Size.Handle.focused)
.ifElse(
{ isScrubberFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onFocusChanged { isScrubberFocused.value = it.isFocused }
.focusRequester(scrubberFocusRequester)
.focusProperties {
up = FocusRequester.Default
down = FocusRequester.Default
left = FocusRequester.Cancel
right = FocusRequester.Cancel
}
.focusable()
) {
Text(
text = "Child Box of Parent Column 1",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
LogCompositions(message = "TvMenuOverlay Scrubber Scope")
}
}
}
AnimatedVisibility(
visible = isVisible,
modifier = modifier
.graphicsLayer { this.translationY = translationY.value }
.align(Alignment.BottomCenter)
.fillMaxWidth()
.height(expandedHeightDp),
enter = fadeIn(),
exit = fadeOut()
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(PlayerMenuComponentTokens.Color.Bg.Container.normal)
.ifElse(
{ isContentRegionFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onFocusChanged {
if (it.hasFocus) {
Logger.d("TEST", "OverlaysState.ExpandedMenu")
updateOverlaysState(OverlaysState.ExpandedMenu)
}
isContentRegionFocused.value = it.hasFocus
}
) {
Text(
text = "Parent Column 2",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
Box(
modifier = Modifier
.padding(
top = PlayerMenuComponentTokens.Padding.Top.Container.normal,
bottom = PlayerMenuComponentTokens.Spacing.btwnTabsSection,
start = PlayerMenuComponentTokens.Padding.LR.Container.normal,
end = PlayerMenuComponentTokens.Padding.LR.Container.normal
)
.fillMaxWidth()
.height(TabsComponentTokens.Height.Bg.TabItem.normal)
.ifElse(
{ isTabsRowFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onKeyEvent { keyEvent ->
val nativeKeyEvent = keyEvent.nativeKeyEvent
if (nativeKeyEvent.isDPadUp()) {
nativeKeyEvent.onAction(
down = { return@onAction true },
up= {
updateOverlaysState(OverlaysState.MetadataWithCollapsedMenu)
return@onAction true
}
)
}
return@onKeyEvent false
}
.onFocusChanged { isTabsRowFocused.value = it.isFocused }
.focusRequester(tabsRowFocusRequester)
.focusProperties {
up = FocusRequester.Default
down = FocusRequester.Default
left = FocusRequester.Cancel
right = FocusRequester.Cancel
}
.focusable()
) {
Text(
text = "Child Box of Parent Column 2",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
LogCompositions(message = "TvMenuOverlay Tabs & Hint Scope")
}
Box(
modifier = Modifier
.padding(bottom = PlayerMenuComponentTokens.Padding.Btm.Container.normal)
.fillMaxSize()
.ifElse(
{ isContentFocused.value },
Modifier.border(2.dp, Color.White),
Modifier.border(2.dp, Color.Yellow)
)
.onFocusChanged { isContentFocused.value = it.isFocused }
.focusRequester(contentFocusRequester)
.focusProperties {
up = FocusRequester.Default
down = FocusRequester.Cancel
left = FocusRequester.Cancel
right = FocusRequester.Cancel
}
.focusable()
) {
Text(
text = "Child Box of Parent Column 2",
color = Color.Green,
fontFamily = FontFamily.Default,
textAlign = TextAlign.Center
)
LogCompositions(message = "TvMenuOverlay Content Scope")
}
}
}
Omkar Amberkar
12/17/2023, 4:59 PMonKeyEvent
for the Child Box of Parent Column 2
when receiving focus and the key event triggers the dpad up lambda which results in the focus being skipped from that composable completely.
I need some guidance on how to handle the focus correctly in the above case to set it first onto Child Box of Parent Column 2
and then show the collapsed menu state.