升级Compose与Material3后ExposedDropdownMenuBox报FocusRequester未初始化错误
解决「FocusRequester is not initialized」崩溃问题
核心原因
升级到Material3 1.0.1后,ExposedDropdownMenuBox内部对焦点管理逻辑做了调整,要求必须使用组件自身作用域提供的focusRequester,而非开发者自定义的实例。自定义的FocusRequester会与组件内部的焦点控制逻辑冲突,从而触发未初始化的异常。
修复步骤
移除自定义的FocusRequester实例
删除代码中自行创建的val focusRequester = remember { FocusRequester() }语句。使用ExposedDropdownMenuBox作用域内的focusRequester
在ExposedDropdownMenuBox的代码块中,直接使用作用域提供的focusRequester绑定到OutlinedTextField,无需额外创建。统一Compose依赖版本
检查build.gradle中所有Compose相关依赖版本统一为1.4.2,同时确保composeCompilerVersion与Compose版本匹配(Compose 1.4.2对应编译器版本为1.4.7,Kotlin版本需为1.8.10),避免版本不一致引发的隐性问题。
修改后的代码示例
@OptIn(ExperimentalMaterial3Api::class) @Composable fun EditLocationsScreen( navController: NavHostController, casinoViewModel: CasinoViewModel ) { Scaffold( topBar = { LocationTopBar(navController = navController)} ) { paddingValues -> Spacer(modifier = Modifier.height(10.dp)) Column( modifier = Modifier .fillMaxSize() .padding(paddingValues) ) { var expanded by remember { mutableStateOf(false) } val casinoNames by casinoViewModel.casinoNames.collectAsState(emptyList()) var name by remember { mutableStateOf("") } Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 10.dp), horizontalArrangement = Arrangement.SpaceBetween ) { Text( text = "Name", fontWeight = FontWeight.Bold, modifier = Modifier .padding(10.dp) .align(Alignment.CenterVertically) ) ExposedDropdownMenuBox( expanded = expanded, onExpandedChange = { expanded = !expanded }, modifier = Modifier .weight(1f) .padding(horizontal = 10.dp) ) { // 直接使用ExposedDropdownMenuBox作用域提供的focusRequester OutlinedTextField( label = { Text(text = "Enter Location") }, value = name, onValueChange = { name = it }, modifier = Modifier .padding(10.dp) .align(Alignment.CenterVertically) .focusRequester(focusRequester) ) ExposedDropdownMenu( expanded = expanded, onDismissRequest = { expanded = false } ) { casinoNames.forEach { casino -> DropdownMenuItem( onClick = { expanded = false name = casino.name }, text = { Text(text = casino.name) } ) } } } } Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 10.dp), ) { Button( onClick = { casinoViewModel.insertCasino(name, casinoNames) name = "" expanded = true }, modifier = Modifier .padding(10.dp) .weight(1f) ) { Text(text = "Add new Casino") } Button( onClick = { casinoViewModel.removeCasino(name, casinoNames) name = "" expanded = true }, modifier = Modifier .padding(10.dp) .weight(1f) ) { Text(text = "Delete Casino") } } } } }
额外注意点
- 点击按钮时,建议先完成数据操作和
name清空,再设置expanded=true,避免状态更新顺序导致的组件重组异常。 - 如果仍存在焦点问题,可在设置
expanded=true后,通过LaunchedEffect延迟请求焦点(需在ExposedDropdownMenuBox作用域内使用其focusRequester)。
内容的提问来源于stack exchange,提问作者JD74
相关产品推荐
相关产品推荐

