Jetpack Compose开发Wordle游戏:OutlinedTextField字符不显示等问题求助
Wordle 游戏开发问题(Jetpack Compose)
我是Android新手,正在学习Jetpack Compose,首个任务是开发类似Wordle的游戏,用户需在N次尝试内猜出隐藏单词。
遇到以下问题:
- 我使用OutlinedTextField构建猜词网格,计划用二维数组(String或Char类型)维护每个输入框的状态,更新状态以触发UI重组,但两种类型均未实现预期效果,请问此思路是否正确?
- 无法定位代码Bug:通过
println打印显示状态已更新为预期值,但OutlinedTextField多数时候不展示该数据,偶尔才显示。 - 希望实现一个显示字母的自定义键盘,点击键盘组件时,对应字符填入当前聚焦的OutlinedTextField,请问应使用哪些UI组件,或是否有更合理的方案?
游戏状态数据类
// state of the Wordle Game data class WordleState( val currentGuess: ArrayList<CharacterToGuess>, //holds the word being guessed, on value change, UI is supposed to get recompose var gameState: GameState = GameState.ONGOING, val wordToGuess: String = getWordFromWordBank(), var remainingAttempts: Int = MAX_GUESSES_ALLOWED, /*var currentGuess: MutableList<MutableList<String>> = MutableList(MAX_GUESSES_ALLOWED) { MutableList(MAX_LETTERS_LENGTH) {""} },*/ var selectedRowIndex: Int = 0 ) { companion object { fun getWordFromWordBank(): String { //TODO: move to the WordFactory val wordBank: List<String> = mutableListOf("AUDIO", "VIDEO", "KITES" ) return wordBank[Random.nextInt(0, wordBank.size-1)] } var MAX_GUESSES_ALLOWED: Int = 1 var MAX_LETTERS_LENGTH: Int = 5 } override fun equals(other: Any?): Boolean { //Android studio suggested this override if (this === other) return true if (javaClass != other?.javaClass) return false other as WordleState if (gameState != other.gameState) return false if (wordToGuess != other.wordToGuess) return false if (remainingAttempts != other.remainingAttempts) return false if (!currentGuess.contentEquals(other.currentGuess)) return false if (selectedRowIndex != other.selectedRowIndex) return false return true } override fun hashCode(): Int { //Android studio suggested this override var result = gameState.hashCode() result = 31 * result + wordToGuess.hashCode() result = 31 * result + remainingAttempts result = 31 * result + currentGuess.contentHashCode() result = 31 * result + selectedRowIndex return result } }
ViewModel中处理输入的代码
class WordleViewModel: ViewModel() { private val _wordleState = MutableLiveData(WordleState()) var state: LiveData<WordleState> = _wordleState ... fun updateCurrentGuessLetter(it: String, col: Int) { val newGuessLetter = it.first() println("onValueChange before: " + "Letter:`$it`" + " currentGuess:${state.value!!.currentGuess.joinToString(separator = "")}," + " states:${state.value}") val updatedGuess = _wordleState.value!!.copy().currentGuess updatedGuess[col] = newGuessLetter _wordleState.value = _wordleState.value!!.copy( currentGuess = updatedGuess ) println("onValueChange after: " + "Letter:`$it`" + " currentGuess:${state.value!!.currentGuess.joinToString(separator = "")}," + " states:${state.value}") } ... }
MainActivity中的Composable代码
fun WordleGrid(viewModel: WordleViewModel, state: WordleState) { val context = LocalContext.current.applicationContext val focusManager = LocalFocusManager.current Column(modifier = Modifier.fillMaxWidth()) { for (row in 0 until WordleState.MAX_GUESSES_ALLOWED) { Row(modifier = Modifier .fillMaxWidth() .height(50.dp)) { for (col in 0 until WordleState.MAX_LETTERS_LENGTH) { MyOutlinedTextField( modifier = Modifier.weight(1f), viewModel = viewModel, state = state, row = row, col = col ) } } } CheckButton( onClick = { viewModel.onSubmitWord() } ) } } @Composable fun MyOutlinedTextField( modifier: Modifier, viewModel: WordleViewModel, state: WordleState, row: Int, col: Int, ) { val isEnabled = (row == state.selectedRowIndex) //state.currentGuess[col].toString(), val focusManager = LocalFocusManager.current OutlinedTextField( //value = state.currentGuess[row][col], //for state as 2D string array value = state.currentGuess[col].toString(), enabled = isEnabled, onValueChange = { if (it.isNotBlank() && it.isNotEmpty()) { //viewModel.updateCurrentGuessLetter(newLetter.first().toString(), row, col) viewModel.updateCurrentGuessLetter(it, col) if(col == WordleState.MAX_LETTERS_LENGTH - 1) { viewModel.onSubmitWord() } else { focusManager.moveFocus(FocusDirection.Right) } } else { println("onValueChange: Ignoring blank/empty letter") } }, singleLine = true, modifier = Modifier .fillMaxSize() .padding(16.dp) .then(modifier), colors = TextFieldDefaults.outlinedTextFieldColors( focusedBorderColor = Color.Blue, unfocusedBorderColor = Color.DarkGray ), textStyle = TextStyle( color = Color.Red, textAlign = TextAlign.Center, //fontSize = 28.sp, ), keyboardOptions = KeyboardOptions.Default.copy( capitalization = KeyboardCapitalization.Characters, autoCorrect = false, keyboardType = KeyboardType.Text, /*imeAction = ( if (col == WordleState.MAX_LETTERS_LENGTH - 1) ImeAction.Done else ImeAction.Next )*/ ), keyboardActions = KeyboardActions( onNext = { // Move focus to the next outlined text field focusManager.moveFocus(FocusDirection.Right) }, onDone = { // Submit the word when the last outlined text field is completed viewModel.onSubmitWord() } ), ) }
若需更多信息,请告知,感谢您的帮助。
内容的提问来源于stack exchange,提问作者user3067435
相关产品推荐
相关产品推荐

