简体   繁体   中英

Livedata in combination with jetpack compose

I'm trying to learn jetpack compose and tried to make an easy app where you can add restaurants together with a score in an overview list using room.

However, everytime I try to type a word in the textfield, the textfield is not updated and remains empty. I would expect that updating the locationName in the onValueChange function would trigger an update of the state as it is part of a LiveData class. How can I solve this without having to make a seperate UI model in my modelView and having it converted to my entity object in case the data needs to be persisted?

My compose function


@Composable
fun AddItemScreenBody(modifier: Modifier = Modifier.Companion) {
    VerticalScroller {
        Column(modifier) {

                var locations = addItemViewNodel.location.observeAsState()
                FilledTextField(
                    value = locations.value!!.locationName,
                    onValueChange = { data -> locations.value!!.locationName = data },
                    label = { Text(stringResource(R.string.name), style = TextStyle(color = Color(0xFFC7C7C7))) })

            }

    }
}

My viewmodel

class AddItemViewModel () : ViewModel() {
    var location : LiveData<LocationEntity> = MutableLiveData(LocationEntity())

}

My data model

    @Entity(tableName = "locations")
    class LocationEntity @Ignore constructor () {
        @PrimaryKey(autoGenerate = true)
        var id: Long = 0
        @ColumnInfo(name = "location_name")
        var  locationName: String = "" 

        constructor (id: Long, locationName: String, category: Category) : this()
        {
            this.id = id
            this.locationName = locationName
        }

    }

With latest compose version (1.0.0-alpha09), for TextField section, you can do something like:

@Composable
fun MyTextField() {
Column(Modifier.padding(16.dp)) {
    val textFieldState = remember { mutableStateOf(TextFieldValue()) }
    TextField(
        value = textState.value,
        onValueChange = { textFieldState.value = it },
        onImeActionPerformed = { imeAction,controller ->
             if (imeAction == ImeAction.Done){
                 locations.value.locationName = textFieldState.value.text
                 controller?.hideSoftwareKeyboard()
             }
        }
    ) 
    Text("text field value is: ${textFieldState.value.text}")
}

Here, instead of saving data while user is typing, data will be saved when user has performed an action.

Don't use Modifier.Companion, use Modifier only.

Don't use vertical scroller, use lazycolumn

Try this in your viewmodel

var _location = MutableLiveData(LocationEntity())
var location: LiveData<LocationEntity>
get() = _location

fun onLocationChange(data){
_locations.value!!. locationName = data //Confirm that u r doing it right.
}

Are you sure your room implementation is correct? No DAO, no repository?

Anyway try this out and let me know

The answer of Habib Kazemi in the comments was the correct one and resolved the issue:

locations.value...locationName = data updating the value won't help instead you should call addItemViewNodel.location.setValue(new Instance of LocationEntity with desired locationName)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM