我有一个Textfield作为搜索栏的屏幕,当屏幕第一次显示时,它会自动聚焦.问题是,在screen rotationsystem theme change(暗模式/亮模式)之后,即使TextField值不为空并且键盘自动关闭,cursor也会在TextField值开始处移动.请帮帮忙,我已经找了两天了.以下是一些代码示例:

编写版本:1.3.0 material 3:1.0.0

SearchBookScreen.kt

val myViewModel = SearchBookViewModel()

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SearchBookScreen(
    modifier: Modifier = Modifier,
    navController: NavController,
    viewModel: SearchBookViewModel = myViewModel,
    filters: Map<SearchFilterType, FilterOptions> = FILTERS
) {
    val focusRequester = remember { FocusRequester() } 

val searchInputValue = viewModel.searchInputValue.value
val filtersState = viewModel.filtersState

LaunchedEffect(Unit) { this.coroutineContext.job.invokeOnCompletion { focusRequester.requestFocus() } }

Scaffold(
    topBar = {
        Column {
            TextField(
                singleLine = true,
                placeholder = {
                    Text(text = stringResource(id = R.string.search_bar))
                },
                value = searchInputValue.text,
                modifier = Modifier
                    .fillMaxWidth()
                    .focusRequester(focusRequester)
                    ,
                onValueChange = {
                    viewModel.onEvent(SearchBookEvent.EnteredSearchValue(it))
                },
                leadingIcon = {
                    IconButton(onClick = {
                        viewModel.onEvent(SearchBookEvent.ClearSearchInput)
                        navController.navigateUp()
                    }
                    ) {
                        Icon(
                            imageVector = Icons.Default.ArrowBack,
                            contentDescription = "Go back"
                        )
                    }
                },
                colors = TextFieldDefaults.textFieldColors(
                    unfocusedIndicatorColor = Color.Transparent,
                    focusedIndicatorColor = Color.Transparent
                ),
                trailingIcon = {
                    IconButton(onClick = { viewModel.onEvent(SearchBookEvent.ClearSearchInput) }) {
                        Icon(imageVector = Icons.Default.Clear, contentDescription = "clear")
                    }
                },
            )

SearchBookViewModel.kt

class SearchBookViewModel: ViewModel() {


private val _searchInputValue = mutableStateOf(TextFieldValue("", selection = TextRange.Zero))
val searchInputValue: State<TextFieldValue> = _searchInputValue


 fun onEvent(event: SearchBookEvent) {
        when (event) {
            is SearchBookEvent.EnteredSearchValue -> {
                _searchInputValue.value = searchInputValue.value.copy(text = event.value, selection = TextRange(event.value.length))
            }
        }
    }

推荐答案

对于 Select 来说,问题就在这里,

value = searchInputValue.text

您正在使用TextFieldValue操作文本,但是您只是使用普通String(TextFieldValue的Text属性)更新了TextFieldValue参数,所以您对TextFieldValue实例所做的任何操作都不会反映到TextField中.

我在您的代码中使用了State<TextFieldValue>'s委托进行了一些修改

val searchInputValue by viewModel.searchInputValue

并将其用作实际值,而不是将其text属性用于TextField,如下所示.

value = searchInputValue

然而,你必须修改它是如何被更新的,所以我也修改了onValueChange,我只使用了.text,因为我不想进一步修改其他部分,让你来修改它.

 onValueChange = {
    viewModel.onEvent(SearchBookEvent.EnteredSearchValue(it.text))
 }

您的TextField实现应该如下所示

TextField(
      singleLine = true,
      placeholder = {
            Text(text = "Type Here")
      },
      value = searchInputValue, // <- notice this
      modifier = Modifier
            .fillMaxWidth()
            .focusRequester(focusRequester),
      onValueChange = {  
             viewModel.onEvent(SearchBookEvent.EnteredSearchValue(it.text)) // <- and this
      }

应用所有这些更改,当您切换主题模式时,光标/ Select 将停留在末尾.

现在,对于键盘问题,最初显示它,我必须实现这个post中的一些东西,在请求焦点之前添加一个延迟,

LaunchedEffect(Unit) {
    delay(200)
    focusRequester.requestFocus()
}

为了在更改主题模式的同时保留键盘,我必须在我的活动中指定这一点.

window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED)

Android相关问答推荐

Kotlin Gzip字符串未按预期工作

fillMaxHeight中的分数在列内不起作用(android jetpack compose)

格雷德的两个星号是什么意思?非路径

穿戴与iPhone连接的安卓操作系统

我正在创建一个简单的连接四个游戏,我需要一个弹出式窗口当你赢了

Android Kotlin ImageView内置于Kotlin ImageView中.适配器未按预期更新

在 Compose 中,当用户持续向下滚动时,LazyColumn 不会显示新项目

是否可以在 Android 应用程序的 Wifi 设置中为 DNS 服务器设置自定义 IP?

错误:无法安装应用程序:INSTALL_PARSE_FAILED_MANIFEST_MALFORMED (React-Native-Android-Studio)

Android:使用依赖项 ViewModelProviderFactory 初始化 ViewModel 的正确方法

Material 3 中的 ModalBottomSheet 用于 compose

Jetpack compose :使用 rememberSaveable 时未应用待处理的合成

在 Jetpack Compose 中重用具有重复代码的列

单击 Jetpack Compose(单选)时,我无法为列表中的单个文本着色

如何在 BasicTextField 中全选焦点

您如何衡量条形图的 4 个类别?

Jetpack compose 绘制形状

关于launchWhenX和repeatOnLifecycle的问题

如何让用户与任意应用程序共享文件?

如何从构建的流对象中发出值