2jan222
2jan222

Reputation: 1934

Using LiveData as state inside Jetpack @Compose functions

I want to use a LiveData<List<DataClass>> to be the source of my state in a @Composable function.

I cannot use the new @Model annotation, I have seen in this talk Link(at 32:06) it is possible to use LiveData, Flow, etc. by invoking the function +observe(/* Data */).

To the problem: I cannot find the function used in the video (+observe()) or any other way to use LiveData as an origin. How can I use LiveData inside my @Compose function?

Project Gradle:

buildscript {
    ext.kotlin_version = '1.3.60-eap-76'
    repositories {
        google()
        jcenter()
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0-alpha04'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

App gradle: Dependencies:

   def lifecycle_version = "2.1.0"
   def compose_version = "0.1.0-dev02"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version"

    implementation "androidx.compose:compose-runtime:$compose_version"
    kapt "androidx.compose:compose-compiler:$compose_version"

    // Android Compose
    implementation "androidx.ui:ui-layout:$compose_version"
    implementation "androidx.ui:ui-foundation:$compose_version"
    implementation "androidx.ui:ui-framework:$compose_version"
    implementation "androidx.ui:ui-tooling:$compose_version"
    implementation "androidx.ui:ui-android-text:$compose_version"
    implementation "androidx.ui:ui-text:$compose_version"
    implementation "androidx.ui:ui-material:$compose_version"


Upvotes: 42

Views: 48963

Answers (4)

ksysha
ksysha

Reputation: 342

As some already pointed out you need to add the new dependency to build.gradle

implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-beta01'

And then simply:

val name: String by viewModel.name.observeAsState("")

If this does not work for you try the next below. The above syntax is clearly the better one and is also recommended but did not work for me.

val nameState: State<String> = viewModel.name.observeAsState("")
nameState.value

See also the documentation about state here https://developer.android.com/jetpack/compose/state#viewmodel-state

Upvotes: 22

vikas kumar
vikas kumar

Reputation: 11018

Here is another way to observe live data using state. There is an extension function for this just include it.

add gradle dependency below one:

implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-beta01'

now just convert your regular LiveData to State for example.

 val breedItems by doggoViewModel.liveBreedData().observeAsState()

Upvotes: 54

fal
fal

Reputation: 3085

0.1.0-dev09 now includes ui-livedata. Example use here.

Upvotes: 11

Vinay Gaba
Vinay Gaba

Reputation: 1214

The +observe method is not available yet but it(or something similar) should be available in a future release of Jetpack Compose.

If you'd like to use a similar functionality before its officially released, you can use this function that I found in this blog post - https://medium.com/swlh/android-mvi-with-jetpack-compose-b0890f5156ac

Posting below for easier consumption

fun <T> observe(data: LiveData<T>) = effectOf<T?> {
    val result = +state<T?> { data.value }
    val observer = +memo { Observer<T> { result.value = it } }

    +onCommit(data) {
        data.observeForever(observer)
        onDispose { data.removeObserver(observer) }
    }

    result.value
}

Update The unary(+) operator and effectOf have been deprecated as of 0.1.0-dev05. Also memo has been renamed to remember Here is what you should use instead -

@Composable
fun <T> observe(data: LiveData<T>): T? {
    var result by state { data.value }
    val observer = remember { Observer<T> { result = it } }

    onCommit(data) {
        data.observeForever(observer)
        onDispose { data.removeObserver(observer) }
    }

    return result
}

Source - https://kotlinlang.slack.com/archives/CJLTWPH7S/p1581276282423600?thread_ts=1581276282.423600

Upvotes: 6

Related Questions