Compose 中 Focus

611 阅读2分钟

在 Jetpack Compose 中,Focus 是用于处理用户界面元素焦点状态的一个重要概念。焦点管理在处理文本输入、键盘事件和无障碍支持等方面尤为重要。Jetpack Compose 提供了一组 API 来处理和管理焦点,包括获取、清除和监听焦点状态变化。

基本概念

  • FocusRequester:用于请求焦点的对象。
  • Modifier.focusRequester:将焦点请求者附加到一个可组合项。
  • Modifier.focusable:使一个可组合项可获得焦点。
  • Modifier.onFocusChanged:监听焦点变化。

示例代码

以下是一个基本的示例,展示了如何在 Jetpack Compose 中使用 FocusRequesterModifier.focusable 来管理焦点:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.focus.*

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun FocusExample() {
    var text by remember { mutableStateOf(TextFieldValue("")) }
    val focusRequester = remember { FocusRequester() }
    val focusManager = LocalFocusManager.current
    val keyboardController = LocalSoftwareKeyboardController.current

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center
    ) {
        BasicTextField(
            value = text,
            onValueChange = { text = it },
            modifier = Modifier
                .focusRequester(focusRequester)
                .focusable()
                .onFocusChanged { focusState ->
                    if (focusState.isFocused) {
                        // 当 TextField 获取焦点时
                        println("TextField has focus")
                    } else {
                        // 当 TextField 失去焦点时
                        println("TextField lost focus")
                    }
                }
                .background(Color.LightGray)
                .padding(8.dp)
        )

        Spacer(modifier = Modifier.height(16.dp))

        Row {
            Button(onClick = { focusRequester.requestFocus() }) {
                Text("获取焦点")
            }

            Spacer(modifier = Modifier.width(16.dp))

            Button(onClick = {
                focusManager.clearFocus()
                keyboardController?.hide()
            }) {
                Text("清除焦点")
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewFocusExample() {
    FocusExample()
}

代码解释

  1. BasicTextField:用于文本输入的基本文本字段。
  2. focusRequester:创建一个 FocusRequester 实例,用于请求焦点。
  3. focusManager:获取当前的焦点管理器,用于清除焦点。
  4. keyboardController:用于显示和隐藏软键盘。
  5. Modifier.focusRequester(focusRequester):将焦点请求者附加到 BasicTextField
  6. Modifier.focusable():使 BasicTextField 可获得焦点。
  7. Modifier.onFocusChanged:监听焦点变化,当 TextField 获得或失去焦点时执行相应的逻辑。
  8. Button:用于手动请求焦点和清除焦点的按钮。

结论

通过以上示例代码,我们展示了如何在 Jetpack Compose 中管理和处理焦点。使用这些 API,您可以更好地控制用户界面的焦点状态,从而提升用户体验和无障碍支持。在实际应用中,您可以根据需求进行更为复杂的焦点管理和事件处理。