как получить viewModel от viewModels? (фрагмент-ktx)

Я работаю с Single viewModel для Activity и всего его фрагмента.

Итак, чтобы инициализировать viewmodel, если нужно написать этот установочный код в onActivityCreated всех фрагментов

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

Я просматривал страницу расширения Android KTX :( см. Здесь)

и я обнаружил, что могу инициализировать модель представления следующим образом:

    // 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 (приложению):

    //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 в своем приложении, их ссылка не найдена.

Мне нужна помощь в том, как использовать эти расширения с некоторыми базовыми примерами, которые я пытался найти, но не нашел.


comment
Принимает ли ваша ViewModel какие-либо параметры, например, репозиторий или БД?   -  person IgorGanapolsky    schedule 29.10.2019
comment
@IgorGanapolsky, да, я работаю с одной виртуальной машиной, общей для всех фрагментов.   -  person Anmol    schedule 30.10.2019
comment
Тогда тебе понадобится ViewModelFactory   -  person IgorGanapolsky    schedule 30.10.2019


Ответы (9)


Atlast у нас есть стабильная версия.

После перехода на implementation 'androidx.fragment:fragment-ktx:1.1.0' я столкнулся с другой проблемой.

Ошибка компилятора:

Невозможно встроить байт-код, созданный с целевой JVM 1.8, в байт-код, который создается с помощью JVM target 1.6

build.gradle (Модуль: приложение)

compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

ссылка

После применения всего вышеперечисленного проблема решена.

Спасибо всем.

person Anmol    schedule 17.11.2019
comment
Я работаю в приложении с несколькими модулями. Есть ли лучший способ, чем объявить этот compileOption в каждом модуле. - person Vikas Pandey; 06.08.2020
comment
@VikasPandey compileOption можно использовать в глобальном проекте build.gradle. - person Paul Stelian; 19.04.2021

пытаться

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

ОБНОВЛЕНИЕ 2021

Это больше не в бета-версии. Он работает с последней стабильной версией на момент написания. Вам также нужно будет импортировать его в файл Kotlin вашего фрагмента.

implementation 'androidx.fragment:fragment-ktx:1.3.2'
import androidx.fragment.app.activityViewModels
person user11729434    schedule 02.07.2019
comment
Я не уверен, хочу ли я перевести свой проект на бета-версию. - person Anmol; 03.07.2019
comment
by viewModels можно вызывать только во фрагменте или тоже в действии? - person IgorGanapolsky; 05.09.2019
comment
@IgorGanapolsky Этот делегат может быть вызван только из фрагмента. Но если вы добавите implementation the "androidx.activity:activity-ktx:1.0.0" зависимость, вы можете использовать аналогичный делегат для Activity. - person Denys Makhov; 06.09.2019
comment
@Anmol Версия в ответе недавно перешла на стабильную. Вы должны быть как минимум на версии 1.1.0 для by ViewModels() - person MowDownJoe; 16.09.2019
comment
@MowDownJoe благодарим за обновление, и теперь проблема исправлена - person Anmol; 17.11.2019
comment
@DenysMakhov Не бывает androidx.activity:activity-ktx - person IgorGanapolsky; 17.01.2020
comment
@IgorGanapolsky developer.android.com/jetpack/androidx/releases/activity - person Denys Makhov; 17.01.2020
comment
Я заставил его работать, когда я использовал activity-ktx 1.1.0 и расширенный FragmentActivity (), а не только Activity () - person tonisives; 29.01.2020
comment
@DenysMakhov Неправильно. fragment-ktx работает как для активности, так и для фрагмента. - person Dr.jacky; 12.11.2020
comment
@ Dr.jacky Да, может, что-то изменилось за ГОД. - person Denys Makhov; 15.11.2020
comment
by viewModels() достаточно в Activity, потому что вы уже в действии, и если вам нужна модель просмотра активности во фрагменте, используйте by activityViewModels() - person Sai; 14.04.2021
comment
@DenysMakhov У меня была эта путаница, и я просмотрел документы, чтобы узнать, есть ли отдельный ktx для действий: / - person SagaRock101; 12.06.2021

Вы используете последнюю альфа-версию:

dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.2.0-alpha01'
}
person Birju Vachhani    schedule 10.07.2019

Функция расширения viewModels (...) была добавлена ​​в версию 1.1. .0-alpha03. Следовательно, чтобы использовать его в своем приложении, вам необходимо реализовать фрагмент-ktx версий, соответствующих 1.1.0-alpah03 или новее.

Я только что узнал об этом и решил использовать версию 1.1. .0-rc01, потому что я не хотел использовать альфа / бета версии.

person sylvery    schedule 16.07.2019
comment
не может использовать его с 1.2.0-alpha02 - person IgorGanapolsky; 05.09.2019

Вы можете реализовать

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

Фактически, реализация BY viewModels в пакете KTX выглядит так, и вы также можете реализовать функцию расширения самостоятельно.

@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)
}
person midFang    schedule 19.11.2020

Попробуй это. Меня устраивает.

implementation "androidx.fragment:fragment-ktx:1.2.5"
person Apps Developer    schedule 27.12.2020

Примечание. Это работает и с Jetpack Compose.

Скопируйте зависимость из ЗДЕСЬ

В настоящее время 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")
}
person ΞXPROPACE    schedule 05.06.2021

Для гуглеров: ваша Activity должна наследовать AppCompatActivity, а не Activity.

person Evgenii Vorobei    schedule 04.07.2021

Если вы пришли сюда в поисках решения для Koin:

Обратите внимание, что вы можете использовать Koin для выполнения этой работы:

private val viewModel by viewModel<NoteViewModel>()

будет использовать импорт

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

из зависимости:

implementation "org.koin:koin-android-viewmodel:+" // изменение + на w / e является последним, когда вы читали это

person Blundell    schedule 16.12.2019
comment
(ответьте, потому что я искал себя, и Google отправил меня сюда!) - person Blundell; 16.12.2019
comment
да, очень сложно получить правильный импорт при использовании koin, но этот вопрос не имеет отношения к коину. - person Anmol; 17.12.2019
comment
Вопрос возник в Google при поиске проблем с Koin (те же симптомы), так что вы никогда не узнаете :) - person Blundell; 17.12.2019
comment
Зачем нужен коин? - person IgorGanapolsky; 17.01.2020
comment
У Koin такой же api. Так что это не обязательно, это альтернатива с той же проблемой. - person Blundell; 17.01.2020
comment
Я просто думаю, что вы лучше подтвердите свой ответ, если объясните, почему вы предлагаете монеты в самом ответе, а не в комментариях. - person Machado; 07.05.2020