Skip to content

Commit 7f93377

Browse files
authored
android/tv: fix focus highlighting on back buttons (#605)
updates tailscale/corp#26199 The back buttons would not highlight properly when they are focussed on Android TV. This pulls in what was implemented for the Avatar. Some small tweaks to the action animation so that it has a nice radius instead of a square box. Signed-off-by: Jonathan Nobels <[email protected]>
1 parent 56d7be3 commit 7f93377

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fun Avatar(
4242
action: (() -> Unit)? = null,
4343
isFocusable: Boolean = false
4444
) {
45-
var isFocused = remember { mutableStateOf(false) }
45+
val isFocused = remember { mutableStateOf(false) }
4646
val focusManager = LocalFocusManager.current
4747

4848
// Outer Box for the larger focusable and clickable area

android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
package com.tailscale.ipn.ui.view
55

66
import androidx.annotation.StringRes
7+
import androidx.compose.foundation.background
78
import androidx.compose.foundation.clickable
89
import androidx.compose.foundation.focusable
910
import androidx.compose.foundation.interaction.MutableInteractionSource
1011
import androidx.compose.foundation.layout.Box
1112
import androidx.compose.foundation.layout.RowScope
1213
import androidx.compose.foundation.layout.padding
1314
import androidx.compose.foundation.layout.width
15+
import androidx.compose.foundation.shape.CircleShape
1416
import androidx.compose.material.icons.Icons
1517
import androidx.compose.material.icons.automirrored.filled.ArrowBack
1618
import androidx.compose.material.icons.filled.CheckCircle
@@ -24,10 +26,14 @@ import androidx.compose.material3.TopAppBar
2426
import androidx.compose.material3.ripple
2527
import androidx.compose.runtime.Composable
2628
import androidx.compose.runtime.LaunchedEffect
29+
import androidx.compose.runtime.mutableStateOf
2730
import androidx.compose.runtime.remember
2831
import androidx.compose.ui.Modifier
32+
import androidx.compose.ui.draw.clip
2933
import androidx.compose.ui.focus.FocusRequester
3034
import androidx.compose.ui.focus.focusRequester
35+
import androidx.compose.ui.focus.onFocusChanged
36+
import androidx.compose.ui.graphics.Color
3137
import androidx.compose.ui.res.stringResource
3238
import androidx.compose.ui.unit.dp
3339
import com.tailscale.ipn.ui.theme.topAppBar
@@ -77,23 +83,32 @@ fun Header(
7783

7884
@Composable
7985
fun BackArrow(action: () -> Unit, focusRequester: FocusRequester) {
80-
val modifier =
86+
val isFocused = remember { mutableStateOf(false) }
87+
88+
val boxModifier =
8189
if (isAndroidTV()) {
8290
Modifier.focusRequester(focusRequester)
83-
.focusable() // Ensure the composable can receive focus
91+
.clip(CircleShape) // Ensure both the focus and click area are circular
92+
.background(
93+
if (isFocused.value) MaterialTheme.colorScheme.surface else Color.Transparent,
94+
)
95+
.onFocusChanged { focusState -> isFocused.value = focusState.isFocused }
96+
.focusable()
8497
} else {
8598
Modifier
8699
}
87100

88-
Box(modifier = modifier.padding(start = 8.dp, end = 8.dp)) {
101+
val iconModifier =
102+
Modifier.clickable(
103+
interactionSource = remember { MutableInteractionSource() },
104+
indication = ripple(bounded = false, radius = 24.dp),
105+
onClick = action)
106+
107+
Box(modifier = boxModifier.padding(start = 8.dp, end = 8.dp)) {
89108
Icon(
90109
Icons.AutoMirrored.Filled.ArrowBack,
91110
contentDescription = "Go back to the previous screen",
92-
modifier =
93-
Modifier.clickable(
94-
interactionSource = remember { MutableInteractionSource() },
95-
indication = ripple(bounded = true),
96-
onClick = action))
111+
modifier = iconModifier)
97112
}
98113
}
99114

0 commit comments

Comments
 (0)