1

I basically have a Composable function with a lambda returning a value which a text composable is supposed to display.


data class CustomUiState(
    val lookupList: HashMap<UUID, MutableList<String>> = HashMap()
)

class CustomViewModel(
): ViewModel() {
    private val _uiState: MutableStateFlow(CustomUiState())
    val uiState: StateFlow<CustomUiState> = _uiState.asStateFlow()

    fun getValue(index: Int) {
        // complex lookup with lookupList
        return ...
    }

    fun updateValue(i: Int, s: String) {
        _uiState.update { state -> 
            state.copy(
                // Update lookupList with new value
                lookupList = ...
            )
        }
    }
}

@Composable
fun Screen(viewModel: CustomViewModel) {

    Widget(
        value = { viewModel.getValue(it) },
        onValueChanged = { i, s viewModel.updateValue(i, s) }
    )
}

@Composable
fun Widget(
    value: (Int) -> String,
    onValueChanged: (Int, String) -> Unit
) {

    LazyRow() {
        items(4) {
            // This does not work
            // Because Compose do not recompose when value(it) changes
            Text(
                text = value(it),
                //lots of other configurations
                ...
            )
        }
    }
}

I have tried Googling but with no luck. What do I need to change to get this to work?

Adding text just because StackOverflow didn't let me post with to little text in the question.

OscarCreator
  • 374
  • 4
  • 13

1 Answers1

1

Change your code this way and see if it recomposes on value change.

class CustomViewModel(
    ): ViewModel() {
        private val _uiState: MutableStateFlow(CustomUiState())
        val uiState: StateFlow<CustomUiState> = _uiState.asStateFlow()

        init {
            getValue(StartingIndexHere)
        }
        fun getValue(index: Int) {
            // complex lookup with lookupList
            //update here _uiState here
            return ...
        }

        fun updateValue(i: Int, s: String) {
            _uiState.update { state ->
                state.copy(
                    // Update lookupList with new value
                    lookupList = ...
                )
            }
        }
    }

    @Composable
    fun Screen(viewModel: CustomViewModel) {

        val uiStateValue = viewModel.uiState.collectAsState()

        Widget(
            value = { uiStateValue.value },
            onValueChanged = { i, s viewModel.updateValue(i, s) }
        )
    }

    @Composable
    fun Widget(
        value: (Int) -> String,
        onValueChanged: (Int, String) -> Unit
    ) {

        LazyRow() {
            items(4) {
                // This does not work
                // Because Compose do not recompose when value(it) changes
                var textValue by remember(value(it)) {
                    mutableStateOf(value(it))
                }
                Text(
                    text = textValue,
                    //lots of other configurations
                    ...
                )
            }
        }
    }
Abdullah Javed
  • 459
  • 3
  • 17