'how to get viewModel by viewModels? (fragment-ktx)

I am working with Single viewModel for the Activity and all of it's fragment.

So to initialise viewmodel if have to write this setup code in onActivityCreated of all the fragment's

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(activity!!).get(NoteViewModel::class.java)
    }

I was going thorough the Android KTX extension page:(refer here)

and i found i can initialise view model like this:

    // Get a reference to the ViewModel scoped to this Fragment
    val viewModel by viewModels<MyViewModel>()

    // Get a reference to the ViewModel scoped to its Activity
    val viewModel by activityViewModels<MyViewModel>()

So I added below dependency's to my gradle(app):

    //ktx android
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.fragment:fragment-ktx:1.0.0'
    implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

But when i try to use viewModels/activityViewModels in my application their reference in not found.

I want help in how to use these extension's with some basic example i tried searching for examples haven't found any.



Solution 1:[1]

Atlast we we have got stable version.

After moving to implementation 'androidx.fragment:fragment-ktx:1.1.0' i faced another issue.

###Compiler Error:

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6

###build.gradle (Module:app)

compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

reference

After applying all the above the issue's is resolved.

Solution 2:[2]

try

implementation 'androidx.fragment:fragment-ktx:1.1.0-beta02'

2021 UPDATE

This is no longer in beta. It works with the latest stable version at the time of writing. You will also need to import it in your fragment's Kotlin file.

implementation 'androidx.fragment:fragment-ktx:1.3.2'
import androidx.fragment.app.activityViewModels

Solution 3:[3]

I think you need to have this dependency for your activity if you want to use kotlin delegations for viewmodel

//ViewModels delegation extentensions for activity
implementation 'androidx.activity:activity-ktx:1.3.1'

Solution 4:[4]

You use this latest alpha version:

dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.2.0-alpha01'
}

Solution 5:[5]

UPDATE 2022 APRIL 29


You should use this:

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.4.1"
}

more information:

https://developer.android.com/topic/libraries/architecture/viewmodel#implement

https://developer.android.com/kotlin/ktx#fragment

Solution 6:[6]

The extension function viewModels(...) was added in version 1.1.0-alpha03. Therefore, in order to use it in your app you will have to implement the fragment-ktx of versions matching 1.1.0-alpah03 or later.

I just found out about this and so I resorted to using version 1.1.0-rc01 because I didn't want to use alpha/beta versions.

Solution 7:[7]

You can implementation

implementation 'androidx.fragment:fragment-ktx:1.1.0'

In fact, the BY viewModels implementation in the KTX package looks like this, and you might as well implement an extension function yourself

@MainThread
inline fun <reified VM : ViewModel> ComponentActivity.viewModels(
        noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        val application = application ?: throw IllegalArgumentException(
                "ViewModel can be accessed only when Activity is attached"
        )
        ViewModelProvider.AndroidViewModelFactory.getInstance(application)
    }

    return ViewModelLazy(VM::class, { viewModelStore }, factoryPromise)
}

Solution 8:[8]

Note : This works for Jetpack Compose too

Copy the dependency from HERE

Currently 2021 June 5 the dependency is as below :

dependencies {
    val activity_version = "1.2.3"

    // Java language implementation
    implementation("androidx.activity:activity:$activity_version")
    // Kotlin
    implementation("androidx.activity:activity-ktx:$activity_version")
}

Solution 9:[9]

Try this one. It works for me.

implementation "androidx.fragment:fragment-ktx:1.2.5"

Solution 10:[10]

For googlers: your Activity should inherit AppCompatActivity, not Activity

Solution 11:[11]

You can fix it by implementing the fragment-ktx library like this

def fragment_version = "1.4.0"

implementation("androidx.fragment:fragment-ktx:$fragment_version")

See more and check latest version here.