【问题标题】:how to get viewModel by viewModels? (fragment-ktx)如何通过 viewModels 获取 viewModel? (片段-ktx)
【发布时间】:2019-11-06 22:55:11
【问题描述】:

我正在为 Activity 及其所有片段使用 Single viewModel。

如果必须在所有片段的onActivityCreated 中编写此设置代码,则初始化viewmodel

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

我正在浏览 Android KTX 扩展页面:(refer here)

我发现我可以像这样初始化视图模型:

    // 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>()

所以我在我的 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"

但是当我尝试在我的应用程序中使用 viewModels/activityViewModels 时,他们的引用找不到。

我需要一些关于如何使用这些扩展的帮助,我尝试搜索示例但没有找到任何基本示例。

【问题讨论】:

  • 您的 ViewModel 是否带有任何参数,例如存储库或数据库?
  • @IgorGanapolsky 是的。我正在使用在所有片段之间共享的单个 VM。
  • 那么你需要一个ViewModelFactory

标签: android androidx android-jetpack kotlin-android-extensions android-viewmodel


【解决方案1】:

我们终于有了稳定版。

转到implementation 'androidx.fragment:fragment-ktx:1.1.0' 后,我遇到了另一个问题。

编译器错误:

无法将使用 JVM 目标 1.8 构建的字节码内联到 使用 JVM 目标 1.6 构建

build.gradle (Module:app)

compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

reference

应用以上所有方法后,问题就解决了。

谢谢大家。

【讨论】:

  • 我在一个多模块应用程序中工作,有没有更好的方法然后将这个 compileOption 声明到每个模块中。
  • @VikasPandey compileOption 可以在全局项目 build.gradle 中使用。
【解决方案2】:

试试

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

2021 年更新

这不再处于测试阶段。它适用于撰写本文时的最新稳定版本。您还需要将其导入片段的 Kotlin 文件中。

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

【讨论】:

  • @IgorGanapolsky 这个委托只能从片段中调用。但是如果你添加implementation the "androidx.activity:activity-ktx:1.0.0"依赖,你可以为Activity使用一个类似的委托。
  • @Anmol 答案中的版本最近升级到了稳定版。 by ViewModels() 至少需要 1.1.0
  • @DenysMakhov 错了。 fragment-ktx 适用于活动和片段。
  • @Dr.jacky 是的,也许一年内发生了一些变化。
  • by viewModels() 在 Activity 中就足够了,因为您已经在 Activity 中,如果您需要在 Fragment 中使用 Activity 的视图模型,请使用 by activityViewModels()
【解决方案3】:

我认为如果你想为 viewmodel 使用 kotlin 委托,你需要对你的活动有这个依赖

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

【讨论】:

  • 谢谢!这就是我的解决方案。
  • 是的,这是正确的答案。谢谢。
【解决方案4】:

您使用的是最新的 alpha 版本:

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

【讨论】:

    【解决方案5】:

    在版本1.1.0-alpha03 中添加了扩展函数viewModels(...)。因此,为了在您的应用程序中使用它,您必须实现匹配 1.1.0-alpah03 或更高版本的 fragment-ktx。

    我刚刚发现了这一点,所以我使用了 1.1.0-rc01 版本,因为我不想使用 alpha/beta 版本。

    【讨论】:

    • 不能与 1.2.0-alpha02 一起使用
    【解决方案6】:

    你可以实现

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

    其实KTX包中的BY viewModels实现是这样的,你还不如自己实现一个扩展函数

    @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)
    }
    

    【讨论】:

      【解决方案7】:

      注意:这也适用于 Jetpack Compose

      HERE复制依赖

      目前2021 June 5的依赖如下:

      dependencies {
          val activity_version = "1.2.3"
      
          // Java language implementation
          implementation("androidx.activity:activity:$activity_version")
          // Kotlin
          implementation("androidx.activity:activity-ktx:$activity_version")
      }
      

      【讨论】:

        【解决方案8】:

        试试这个。它对我有用。

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

        【讨论】:

          【解决方案9】:

          Google 员工:您的 Activity 应该继承 AppCompatActivity,而不是 Activity

          【讨论】:

          • 感谢您的关注!
          【解决方案10】:

          您可以通过像这样实现 fragment-ktx 库来修复它

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

          查看更多并查看最新版本here

          【讨论】:

            【解决方案11】:

            如果您来这里寻找 Koin 的解决方案

            请注意,您可以使用 Koin 来完成这项工作:

            private val viewModel by viewModel&lt;NoteViewModel&gt;()

            会使用导入

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

            来自依赖:

            implementation "org.koin:koin-android-viewmodel:+" // 当你读到这篇文章时,将 + 改为 w/e 是最新的

            【讨论】:

            • (回答是因为我在找自己,谷歌把我发到这里了!)
            • 是的,在使用 koin 时,正确导入是非常棘手的,但这个问题与 koin 无关。
            • 谷歌搜索 Koin 问题时出现的问题,(相同的症状)所以你永远不知道:)
            • 为什么需要 Koin?
            • Koin 有相同的 api。所以没有必要,它是有同样问题的替代方案。
            猜你喜欢
            • 1970-01-01
            • 2018-01-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-10
            • 1970-01-01
            • 1970-01-01
            • 2018-10-22
            相关资源
            最近更新 更多