Как получить 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>()

Итак, я добавил ниже зависимости к моему градиенту (приложению):

    //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 29.10.2019 15:22

@IgorGanapolsky да, это так. Я работаю с одной виртуальной машиной, совместно используемой всеми фрагментами.

Anmol 30.10.2019 16:29

Тогда вам понадобится ViewModelFactory

IgorGanapolsky 30.10.2019 16:49
103
3
70 407
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

пытаться

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

ОБНОВЛЕНИЕ 2021

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

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

Я не уверен, хочу ли я перевести свой проект в бета-версию.

Anmol 03.07.2019 08:29
by viewModels можно вызывать только во Фрагменте или в активности тоже?
IgorGanapolsky 05.09.2019 20:23

@IgorGanapolsky Этот делегат может быть вызван только из Фрагмента. Но если вы добавите зависимость implementation the "androidx.activity:activity-ktx:1.0.0", вы можете использовать аналогичный делегат для Activity.

Denys Makhov 06.09.2019 11:36

@Anmol Версия в ответе недавно перешла на стабильную. У вас должна быть версия не ниже 1.1.0 для by ViewModels()

MowDownJoe 16.09.2019 19:31

@MowDownJoe спасибо за обновление, теперь проблема исправлена

Anmol 17.11.2019 09:44

@DenysMakhov Нет такой вещи, как androidx.activity:activity-ktx

IgorGanapolsky 17.01.2020 01:52

@ИгорьГанапольский developer.android.com/jetpack/androidx/релизы/активность

Denys Makhov 17.01.2020 07:32

У меня это заработало, когда я использовал activity-ktx 1.1.0 и расширил FragmentActivity(), а не только Activity()

tonisives 29.01.2020 04:26

@ДенисМахов Неправильно. fragment-ktx работает как для активности, так и для фрагмента.

Dr.jacky 12.11.2020 11:48

@Dr.jacky Да, может быть, что-то изменилось за ГОД.

Denys Makhov 15.11.2020 15:35
by viewModels() достаточно в действии, потому что вы уже в действии, и если вам нужна модель представления действия во фрагменте, используйте by activityViewModels()
Sai 14.04.2021 13:52

@DenysMakhov У меня была эта путаница, и я просмотрел документы, чтобы узнать, есть ли отдельный ktx для действий: /

SagaRock101 12.06.2021 09:27

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

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

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

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

нельзя использовать с 1.2.0-альфа02

IgorGanapolsky 05.09.2019 20:35
Ответ принят как подходящий

Наконец-то мы получили стабильную версию.

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

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

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

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

compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

ссылка

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

Всем спасибо.

Я работаю в приложении с несколькими модулями. Есть ли лучший способ, чем объявить этот compileOption в каждом модуле.

Vikas Pandey 06.08.2020 13:33

@VikasPandey compileOption можно использовать в глобальном проекте build.gradle.

Paul Stelian 19.04.2021 22:54

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

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

private val viewModel by viewModel<NoteViewModel>()

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

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

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

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

(ответ, потому что я искал сам, и гугл отправил меня сюда!)

Blundell 16.12.2019 17:54

да, очень сложно иметь правильный импорт при использовании koin, но этот вопрос не связан с коином.

Anmol 17.12.2019 07:37

Вопрос возник в Google при поиске проблем с Koin (те же симптомы), так что никогда не знаешь :)

Blundell 17.12.2019 13:06

Зачем нужен Коин?

IgorGanapolsky 17.01.2020 01:53

Коин имеет тот же API. Так что это не обязательно, это альтернатива с той же проблемой.

Blundell 17.01.2020 09:52

Я просто думаю, что вы лучше подтвердите свой ответ, если объясните, почему вы предлагаете монету в самом ответе вместо комментариев.

Machado 07.05.2020 16:04

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

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

На самом деле реализация viewModels BY в пакете 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)
}

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

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

Примечание. Это работает и для 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")
}

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

Спасибо, что заметили это!

Dmitriy Pavlukhin 07.10.2021 18:55

Я думаю, вам нужна эта зависимость для вашей деятельности, если вы хотите использовать делегирование kotlin для модели представления.

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

Спасибо! Это было решением для меня.

Cata 14.11.2021 20:07

Да, это правильный ответ. Спасибо.

Jake Schnorr 26.02.2022 19:15

Вы можете исправить это, внедрив библиотеку fragment-ktx следующим образом.

def fragment_version = "1.4.0"

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

Узнайте больше и проверьте последнюю версию здесь.

Другие вопросы по теме