按钮 onClick 继续替换 mutableStateList 中的值
Button onClick keep replacing values in mutableStateList
我正在尝试显示一个 4x4 网格,其值会根据用户输入而变化。为实现这一点,我创建了 mutableStateListOf,我在 ViewModel 中使用它来保存配置更改。但是,当我尝试使用按钮 onClick 替换该特定列表中的值时,它会一直这样做,直到应用程序崩溃。我不明白为什么单击按钮一次后 onReplaceGridContent 会循环。目前,我的代码如下所示:
视图模型:
class GameViewModel : ViewModel(){
var gameGridContent = mutableStateListOf<Int>()
private set // Restrict writes to this state object to private setter only inside view model
fun replaceGridContent(int: Int, index: Int){
gameGridContent[index] = int
}
fun removeGridContent(index: Int){
gameGridContent[index] = -1
}
fun initialize(){
for(i in 0..15){
gameGridContent.add(-1)
}
val firstEmptyGridTile = GameUtils.getRandomTilePosition(gameGridContent)
val firstGridNumber = GameUtils.getRandomTileNumber()
gameGridContent[firstEmptyGridTile] = firstGridNumber
}
}
按钮:
Button(
onClick = {
onReplaceGridContent(GameUtils.getRandomTileNumber(),GameUtils.getRandomTilePosition(gameGridContent))},
colors = Color.DarkGray
){
Text(text = "Add number to tile")
}
Activity 可组合:
@Composable
fun gameScreen(gameViewModel: GameViewModel){
gameViewModel.initialize()
MainStage(
gameGridContent = gameViewModel.gameGridContent,
onReplaceGridContent = gameViewModel::replaceGridContent,
onRemoveGridContent = gameViewModel::removeGridContent
)
}
你的 initialize
实际上 运行 每次重组 gameScreen
:
- 您单击一个图块 - 状态变化导致重新组合。
initializa
被调用并再次改变状态导致重组。
- 步骤 2 一次又一次地发生。
您应该改为在其构造函数中初始化您的视图模型(或使用布尔标志强制执行一次 tim 初始化)以使其仅执行一次。
只需将其更改为构造函数:
class GameViewModel : ViewModel(){
var gameGridContent = mutableStateListOf<Int>()
private set // Restrict writes to this state object to private setter only inside view model
fun replaceGridContent(int: Int, index: Int){
gameGridContent[index] = int
}
fun removeGridContent(index: Int){
gameGridContent[index] = -1
}
init {
for(i in 0..15){
gameGridContent.add(-1)
}
val firstEmptyGridTile = GameUtils.getRandomTilePosition(gameGridContent)
val firstGridNumber = GameUtils.getRandomTileNumber()
gameGridContent[firstEmptyGridTile] = firstGridNumber
}
}
现在您不需要在可组合项中调用初始化:
@Composable
fun gameScreen(gameViewModel: GameViewModel){
MainStage(
gameGridContent = gameViewModel.gameGridContent,
onReplaceGridContent = gameViewModel::replaceGridContent,
onRemoveGridContent = gameViewModel::removeGridContent
)
}
我正在尝试显示一个 4x4 网格,其值会根据用户输入而变化。为实现这一点,我创建了 mutableStateListOf,我在 ViewModel 中使用它来保存配置更改。但是,当我尝试使用按钮 onClick 替换该特定列表中的值时,它会一直这样做,直到应用程序崩溃。我不明白为什么单击按钮一次后 onReplaceGridContent 会循环。目前,我的代码如下所示:
视图模型:
class GameViewModel : ViewModel(){
var gameGridContent = mutableStateListOf<Int>()
private set // Restrict writes to this state object to private setter only inside view model
fun replaceGridContent(int: Int, index: Int){
gameGridContent[index] = int
}
fun removeGridContent(index: Int){
gameGridContent[index] = -1
}
fun initialize(){
for(i in 0..15){
gameGridContent.add(-1)
}
val firstEmptyGridTile = GameUtils.getRandomTilePosition(gameGridContent)
val firstGridNumber = GameUtils.getRandomTileNumber()
gameGridContent[firstEmptyGridTile] = firstGridNumber
}
}
按钮:
Button(
onClick = {
onReplaceGridContent(GameUtils.getRandomTileNumber(),GameUtils.getRandomTilePosition(gameGridContent))},
colors = Color.DarkGray
){
Text(text = "Add number to tile")
}
Activity 可组合:
@Composable
fun gameScreen(gameViewModel: GameViewModel){
gameViewModel.initialize()
MainStage(
gameGridContent = gameViewModel.gameGridContent,
onReplaceGridContent = gameViewModel::replaceGridContent,
onRemoveGridContent = gameViewModel::removeGridContent
)
}
你的 initialize
实际上 运行 每次重组 gameScreen
:
- 您单击一个图块 - 状态变化导致重新组合。
initializa
被调用并再次改变状态导致重组。- 步骤 2 一次又一次地发生。
您应该改为在其构造函数中初始化您的视图模型(或使用布尔标志强制执行一次 tim 初始化)以使其仅执行一次。
只需将其更改为构造函数:
class GameViewModel : ViewModel(){
var gameGridContent = mutableStateListOf<Int>()
private set // Restrict writes to this state object to private setter only inside view model
fun replaceGridContent(int: Int, index: Int){
gameGridContent[index] = int
}
fun removeGridContent(index: Int){
gameGridContent[index] = -1
}
init {
for(i in 0..15){
gameGridContent.add(-1)
}
val firstEmptyGridTile = GameUtils.getRandomTilePosition(gameGridContent)
val firstGridNumber = GameUtils.getRandomTileNumber()
gameGridContent[firstEmptyGridTile] = firstGridNumber
}
}
现在您不需要在可组合项中调用初始化:
@Composable
fun gameScreen(gameViewModel: GameViewModel){
MainStage(
gameGridContent = gameViewModel.gameGridContent,
onReplaceGridContent = gameViewModel::replaceGridContent,
onRemoveGridContent = gameViewModel::removeGridContent
)
}