Home > Mobile >  Why recomposition doesn't happen when TextFieldValue changes
Why recomposition doesn't happen when TextFieldValue changes

Time:06-27

//My ViewModel

val names = listOf( "valeria", "Daniela", "Isabella", "Liam", "Noah", "Jack", "Oliver", "Ava", "Sophia", "Amelia" ) private val _namesList = MutableStateFlow(names) val namesList = _namesList.asStateFlow()

fun getFilteredNames(state: MutableState<TextFieldValue>) {
    viewModelScope.launch {
        val searchedText = state.value.text
        _namesList.value =
            if (searchedText.isEmpty()) {
                names
            } else {
                val resultList = ArrayList<String>()
                for (item in names) {
                    if (item.lowercase(Locale.getDefault())
                            .contains(searchedText.lowercase(Locale.getDefault()))
                    ) {
                        resultList.add(item)
                    }
                }
                Log.d("List: ", namesList.value.toString())
                resultList
            }
    }
}

//Recomposition doesn't happen for some reason!

val viewModel: MainViewModel = viewModel()
 val names = viewModel.namesList.collectAsState()
    LazyColumn(
        modifier = Modifier
            .fillMaxSize().background(MaterialTheme.colors.background)
    ) {
        items(names.value.size) {
            SearchListItem(names.value[it]) {}
        }
    }

CodePudding user response:

Once I had the same question (you can see it and some other answers here). if shortly, flow is updated only when you emit the new object to it (with different hashcode than the last emitted item). and you are updating the same list and then trying to pass it to flow. if you will create the copy of the list and emit this copy, everything will work ok, as it is already another object

CodePudding user response:

So I am not sure how are you using this callback to get more items. Simplified it would be like:

val mutableNamesList = MutableStateFlow(listOf<String>())
val namesList = mutableNamesList.asStateFlow()

@Composable
fun NamesList() {
    val coroutineScope = rememberCoroutineScope()
    var text by remember { mutableStateOf("") }
    TextField(value = text, onValueChange = { newTextValue ->
        text = newTextValue
        coroutineScope.launch {
            mutableNamesList.value = ( mutableNamesList.value   newTextValue)
        }
    })
   val list =  namesList.collectAsState().value
    LazyColumn {
        items(list) { item ->
            Text(text = item)
        }
    }
}

Just, I used this import:

import androidx.compose.foundation.lazy.items
  • Related