143

I am working with Single viewModel for the Activity and all of its 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.

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Anmol
  • 8,110
  • 9
  • 38
  • 63

13 Answers13

116

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.

Boken
  • 4,825
  • 10
  • 32
  • 42
Anmol
  • 8,110
  • 9
  • 38
  • 63
67

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
germanfr
  • 547
  • 5
  • 19
user11729434
  • 671
  • 4
  • 2
32

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'
Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
Bekzhan
  • 485
  • 5
  • 11
15

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

ONVETI
  • 352
  • 3
  • 11
  • Whilst this may theoretically answer the question, [it would be preferable](//meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. i.e. please [edit] your answer to say *why* this is preferred as of April 2022. – Adriaan Apr 28 '22 at 13:22
  • @Adriaan suggested the right thing. It would be better if the main sample references rather than sharing just web links for the solution. – A S M Sayem May 04 '22 at 19:37
3

You use this latest alpha version:

dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.2.0-alpha01'
}
Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
3

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")
}
Rishad Baniya
  • 665
  • 8
  • 14
3

For googlers: your Activity should inherit AppCompatActivity, not Activity

Evgenii Vorobei
  • 1,457
  • 18
  • 20
3

Be sure to use val and not var for your ViewModel property if you get error of cannot find setter.

htafoya
  • 18,261
  • 11
  • 80
  • 104
2

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.

sylvery
  • 161
  • 1
  • 7
2

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)
}
midFang
  • 96
  • 3
1

Try this one. It works for me.

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

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.

-5

If you have come here looking for a solution for Koin:

Note you can use use Koin to make this work:

private val viewModel by viewModel<NoteViewModel>()

would use the import

import org.koin.android.viewmodel.ext.android.viewModel

from the dependency:

implementation "org.koin:koin-android-viewmodel:+" // change + to w/e is the latest when u read this

Blundell
  • 75,855
  • 30
  • 208
  • 233