android-jetpack-composetextfieldstyled-componentsandroid-jetpackwordpress-jetpack

OutlineTextField text not changed


i am a beginner developer in android dev, i have some problem with OutlineTextField, the case is I want to edit data that already exists in the OutlineTextField but the text that is obtained from the database cannot be deleted, can anyone help me to find the solution of this problem ?

here is my code :

//BookDetails

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BookDetails(id: Int, booksViewModel: BooksViewModel) {

    var nameState = remember {mutableStateOf((""))}



    LaunchedEffect(Unit) {
        booksViewModel.getBook(id)
    }
    booksViewModel.getBook(id)
    val book = booksViewModel.getBook.observeAsState().value
    book?.let {
        nameState.value = it.name
    }

    book ?: return
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(20.dp)
                .verticalScroll(rememberScrollState())
        ) {
            AsyncImage(
                model = "https://picsum.photos/id/24/500",
                contentDescription = null,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(400.dp),
                contentScale = ContentScale.FillBounds
            )
            Spacer(modifier = Modifier.height(20.dp))
            OutlinedTextField(
                value = nameState.value,
                onValueChange = { nameState.value = it },
                label = { Text(stringResource(id = R.string.book_name)) },
                placeholder = {book.name}
            )
        }
}

Solution

  • I think when you change the text in the OutlinedTextField, and thus a recomposition is triggered, you immediately overwrite the new value with the value from the database here:

    book?.let {
        nameState.value = it.name  // overwrite
    }
    

    The question is whether you directly want to overwrite the value in the database if you change the text, or if you only want to store it locally in the nameState. I assume that you want to save the new text locally in nameState and save it to the database later.

    In order to make this work, you could try the following code:

    var nameState: String? by remember { mutableStateOf(null) }
    

    Then, in your OutlinedTextField, do

    OutlinedTextField(
        value = nameState ?: book.name,  // display database text if no modified text available
        onValueChange = { nameState = it },  // save any changes into nameState
        label = { Text(stringResource(id = R.string.book_name)) },
        placeholder = { 
            Text(text = book.name))
        }
    )
    

    Note that the placeholder attribute needs a Composable, not a String.