Search code examples
android-jetpack-composeandroid-jetpack-compose-ui

Problem, Recomposition is not happening when i change UI State (2d LIST) in android jetpack compose


My problem is that i change the uiState but the effect is not there

class BoardViewModel : ViewModel() {
    private var board = mutableListOf<MutableList<Piece?>>()
    private val _uiState = MutableStateFlow(BoardUiState(board.toList()))
    val uiState: StateFlow<BoardUiState> = _uiState.asStateFlow()
    private var selectedPos: Pair<Int, Int>? = null

    init{
        reset()
    }

    private fun reset(){
        board = mutableListOf()
        // this that are not required 
        _uiState.value = BoardUiState(board)
    }

    fun onCellClicked(r: Int, c: Int){
        if(selectedPos != null) {
            move(selectedPos!!.first, selectedPos!!.second, r, c) // i verified this is executed
            selectedPos = null
        }
        else if(board[r][c] != null){
            selectedPos = r to c
        }
    }

    private fun move(sr: Int, sc: Int, dr: Int, dc: Int){
        val temp = board[sr][sc]
        board[sr][sc] = null
        board[dr][dc] = temp
        _uiState.update { currentState ->
            currentState.copy(board = board.toList()) // here im updating the state

             // PROBLEM HERE EVEN WHEN THE BOARD IS CHANGED THE EFFECT IS NOT THERE ON COMPOSITION
        }
    }
}

I verified that the problem is not in other parts of the program, i added dummy int variable to state and changed it in the move function, this time the change happened.

The problem is that change to board is not being detected.

Thanks in advance!


Solution

  • MutableStateFlow uses structural equality comparison == whenever you update it's value (same goes for mutableStateOf by default), the update will never happen as the structure of the new list is the same as the old (mutated) one, the toList extension function will create a new list with the same elements.

    docs:

    https://kotlinlang.org/docs/equality.html

    https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-state-flow/