Jetpack Compose: перемещение вверх и вниз по нескольким многострочным полям BasicTextField с помощью физической клавиатуры

Я заметил, что если у меня есть несколько многострочныхв, если одно из текстовых полей имеет фокус, и я нажимаю клавиши со стрелками вверх и вниз на своей физической клавиатуре (используя эмулятор Android Studio), фокус перемещается в другое текстовое поле вместо перехода вверх или вниз к другой строке текста внутри текстовое поле.

Мне нравится идея позволить клавишам со стрелками вверх и вниз менять фокус, но только если курсор находится в первой или последней строке.

Я придумал решение, но мне интересно, есть ли более простой способ сделать это. Кроме того, если я хочу разрешить изменение фокуса с помощью клавиш со стрелками И с помощью других методов, кажется, мне придется как-то изменить это, чтобы проверить клавишу, которая была нажата с помощью одного из этих модификаторов клавиш, но я не уверен, что это лучший способ сделать это. Знаете ли вы, как определить, вызывает ли нажатие клавиши перемещение/изменение фокуса?

      class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Column {
                repeat(5) {
                    BasicTextFieldWithText()
                }
            }
        }
    }
}
      @OptIn(ExperimentalComposeUiApi::class)
@Composable
fun BasicTextFieldWithText() {
    var text by remember {
        mutableStateOf(
            TextFieldValue("BasicTextField\n" + "with multiple lines\n" + "of text")
        )
    }

    var textLayout by remember {
        mutableStateOf<TextLayoutResult?>(null)
    }

    val atFirstLine by remember {
        derivedStateOf {
            textLayout?.let {
                val range = text.selection
                range.collapsed && it.getLineForOffset(range.end) == 0
            } ?: false
        }
    }

    val atLastLine by remember {
        derivedStateOf {
            textLayout?.let {
                val range = text.selection
                range.collapsed && it.getLineForOffset(range.end) == (it.lineCount - 1)
            } ?: false
        }
    }

    BasicTextField(
        value = text,
        onValueChange = { text = it },
        onTextLayout = { textLayout = it },
        modifier = Modifier
            .border(1.dp, Color.Blue)
            .padding(8.dp)
            .focusProperties {
                up = if (atFirstLine) FocusRequester.Default else FocusRequester.Cancel
                down = if (atLastLine) FocusRequester.Default else FocusRequester.Cancel
            }
    )
}

0 ответов

Другие вопросы по тегам