rows: restore the last-focused card when moving between rows (#29)
Moving up/down between the Home rows (and the Channels rows) jumped to the geometrically-nearest card, so the row shifted left/right and felt inconsistent. A focusRestorer on each row now lands focus on the card that row last had, so the rows stay put as you move between them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a6d0f9ec6c
commit
e485caa855
2 changed files with 10 additions and 0 deletions
|
|
@ -37,6 +37,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
|
@ -439,6 +440,7 @@ private fun absoluteAvatar(avatar: Avatar): String =
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Horizontal row of channel cards, eased scroll-in; LEFT at row start -> drawer. */
|
/** Horizontal row of channel cards, eased scroll-in; LEFT at row start -> drawer. */
|
||||||
|
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun ChannelRow(
|
private fun ChannelRow(
|
||||||
channels: List<VideoChannelDto>,
|
channels: List<VideoChannelDto>,
|
||||||
|
|
@ -481,6 +483,8 @@ private fun ChannelRow(
|
||||||
|
|
||||||
LazyRow(
|
LazyRow(
|
||||||
state = rowState,
|
state = rowState,
|
||||||
|
// Land on the last-focused card when moving between rows (issue #29).
|
||||||
|
modifier = Modifier.focusRestorer { focusRequesters[focusedIndex.coerceAtLeast(0)] ?: FocusRequester.Default },
|
||||||
contentPadding = PaddingValues(horizontal = 12.dp),
|
contentPadding = PaddingValues(horizontal = 12.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -424,6 +425,7 @@ fun ShimmerRow(size: Int = 4) {
|
||||||
* viewport, the row animates it to the left edge (SmartTube behaviour) instead of
|
* viewport, the row animates it to the left edge (SmartTube behaviour) instead of
|
||||||
* the abrupt jump the built-in lazy scroll produces.
|
* the abrupt jump the built-in lazy scroll produces.
|
||||||
*/
|
*/
|
||||||
|
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FocusScrollRow(
|
fun FocusScrollRow(
|
||||||
videos: List<VideoDto>,
|
videos: List<VideoDto>,
|
||||||
|
|
@ -489,6 +491,10 @@ fun FocusScrollRow(
|
||||||
}
|
}
|
||||||
LazyRow(
|
LazyRow(
|
||||||
state = rowState,
|
state = rowState,
|
||||||
|
// Jumping between rows lands on the card this row last had focus on, not
|
||||||
|
// the geometrically-nearest one (issue #29): the rows stop shifting
|
||||||
|
// left/right as you move up and down between them.
|
||||||
|
modifier = Modifier.focusRestorer { focusRequesters[focusedIndex.coerceAtLeast(0)] ?: FocusRequester.Default },
|
||||||
contentPadding = PaddingValues(horizontal = 12.dp),
|
contentPadding = PaddingValues(horizontal = 12.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue