Как назначить фокус на ту же позицию при возврате на экран?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как назначить фокус на ту же позицию при возврате на экран?

Сообщение Anonymous »

Я работаю над проектом для Android TV, уникальной особенностью этой платформы является то, что пользователь перемещает фокус по экрану с помощью пульта дистанционного управления.
Вот экран :
Изображение

При работе с фокусом есть две основные задачи:
  • При навигации слева направо и наоборот фокус не должен путать позиции . Например, если пользователь щелкнет вправо от левой панели 0 -> Правая панель 0, затем перейдет к правой панели 2, а затем щелкнет влево, фокус должен вернуться на левую панель 0. потому что пользователь переместил фокус с левой панели на правую. Эта функциональность была реализована с помощью focusRestorer и уже работает.
  • Когда пользователь нажимает на элемент на правой панели (например, , Правая панель 1), откроется второй экран. Когда пользователь нажимает кнопку «Назад» и возвращается к первому экрану, ожидается, что фокус будет на кнопке, открывшей экран, то есть на правой панели 1. Однако по какой-то причине это работает только в 30 % случаев, и вместо фокусировки на ожидаемой кнопке фокусируется другая кнопка.
ScreenRecord -> https://drive.google.com/file/d/1NCal4k ... SSlUb/view
Есть готовый код:

Код: Выделить всё

private const val FIRST_SCREEN_ROUTE = "first_screen"
private const val SECOND_SCREEN_ROUTE = "second_screen"
private const val DEFAULT_FOCUS_POSITION = -1

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Test_delete_itTheme {
Surface(
modifier = Modifier.fillMaxSize(),
shape = RectangleShape
) {
Greeting()
}
}
}
}
}

@Composable
fun Greeting() {
val navigator: NavHostController = rememberNavController()

NavHost(
navController = navigator,
startDestination = FIRST_SCREEN_ROUTE
) {
composable(FIRST_SCREEN_ROUTE) {
DisposableEffect(Unit) {
Log.e("HERE", "1 CREATED first_screen_route")

onDispose {
Log.e("HERE", "DISPOSED first_screen_route")
}
}

FirstScreen(onClick = {
Log.e("HERE", "NAVIGATION TO SECOND SCREEN")
navigator.navigate(SECOND_SCREEN_ROUTE)
})
}

composable(SECOND_SCREEN_ROUTE) {
DisposableEffect(Unit) {
Log.e("HERE", "CREATED second_screen_route")

onDispose {
Log.e("HERE", "DISPOSED second_screen_route")
}
}

SecondScreen()
}
}
}

@Composable
fun SecondScreen() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Red.copy(alpha = 0.1f)),
contentAlignment = Alignment.Center
) {
Text(text = "SECOND SCREEN")
}
}

@Composable
fun FirstScreen(
onClick: () -> Unit
) {
var focusBtnIdx by rememberSaveable { mutableIntStateOf(DEFAULT_FOCUS_POSITION) }

Row(modifier = Modifier
.fillMaxSize()
) {
LeftPanel()
RightPanel(onClick = onClick, focusBtnIdx = focusBtnIdx, setFocusBtnIdx = { focusBtnIdx = it })
}
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun RowScope.LeftPanel() {
val firstItemFr = remember { FocusRequester() }
val buttons by rememberSaveable { mutableStateOf(List(5) { "Button ${it + 1}" }) }

LaunchedEffect(Unit) {
this.coroutineContext.job.invokeOnCompletion {
try { firstItemFr.requestFocus() }
catch (e: Exception) {/* do nothing */ }
}
}

TvLazyColumn(
modifier = Modifier
.focusRestorer { firstItemFr }
.background(Color.Blue.copy(alpha = 0.1f))
.fillMaxHeight()
.weight(1f),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
itemsIndexed(
items = buttons,
key = { idx, _ -> idx }
) { idx, _ ->
Button(
modifier = Modifier
.let { modifier ->
if (idx == 0) {
modifier.focusRequester(firstItemFr)
} else {
modifier
}
},
onClick = {}
) {
Text(text = "Left Panel: $idx")
}
}
}
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun RowScope.RightPanel(
onClick: () -> Unit,
focusBtnIdx: Int,
setFocusBtnIdx: (Int) -> Unit
) {
val firstItemFr = remember { FocusRequester() }

LaunchedEffect(Unit) {
this.coroutineContext.job.invokeOnCompletion {
try {
Log.e("HERE", ">>>  REQUEST FOCUS")
if (focusBtnIdx != DEFAULT_FOCUS_POSITION) {
firstItemFr.requestFocus()
Log.e("HERE", "

Подробнее здесь: [url]https://stackoverflow.com/questions/78708685/how-to-assign-focus-to-the-same-position-when-returning-to-the-screen[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»