Я работаю с 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 в своем приложении, их ссылка не найдена.
Мне нужна помощь в том, как использовать эти расширения с некоторыми базовыми примерами, которые я пытался найти, но не нашел.
@IgorGanapolsky да, это так. Я работаю с одной виртуальной машиной, совместно используемой всеми фрагментами.
Тогда вам понадобится ViewModelFactory
пытаться
implementation 'androidx.fragment:fragment-ktx:1.1.0-beta02'
Это больше не бета-версия. Он работает с последней стабильной версией на момент написания. Вам также нужно будет импортировать его в файл Kotlin вашего фрагмента.
implementation 'androidx.fragment:fragment-ktx:1.3.2'
import androidx.fragment.app.activityViewModels
Я не уверен, хочу ли я перевести свой проект в бета-версию.
by viewModels можно вызывать только во Фрагменте или в активности тоже?
@IgorGanapolsky Этот делегат может быть вызван только из Фрагмента. Но если вы добавите зависимость implementation the "androidx.activity:activity-ktx:1.0.0", вы можете использовать аналогичный делегат для Activity.
@Anmol Версия в ответе недавно перешла на стабильную. У вас должна быть версия не ниже 1.1.0 для by ViewModels()
@MowDownJoe спасибо за обновление, теперь проблема исправлена
@DenysMakhov Нет такой вещи, как androidx.activity:activity-ktx
@ИгорьГанапольский developer.android.com/jetpack/androidx/релизы/активность
У меня это заработало, когда я использовал activity-ktx 1.1.0 и расширил FragmentActivity(), а не только Activity()
@ДенисМахов Неправильно. fragment-ktx работает как для активности, так и для фрагмента.
@Dr.jacky Да, может быть, что-то изменилось за ГОД.
by viewModels() достаточно в действии, потому что вы уже в действии, и если вам нужна модель представления действия во фрагменте, используйте by activityViewModels()@DenysMakhov У меня была эта путаница, и я просмотрел документы, чтобы узнать, есть ли отдельный ktx для действий: /
Вы используете эту последнюю альфа-версию:
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
Наконец-то мы получили стабильную версию.
После перехода на 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
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
kotlinOptions {
jvmTarget = "1.8"
}
После применения всего вышеперечисленного проблема решена.
Я работаю в приложении с несколькими модулями. Есть ли лучший способ, чем объявить этот compileOption в каждом модуле.
@VikasPandey compileOption можно использовать в глобальном проекте build.gradle.
Если вы пришли сюда в поисках решения для Koin:
Обратите внимание, что вы можете использовать Koin для выполнения этой работы:
private val viewModel by viewModel<NoteViewModel>()
будет использовать импорт
import org.koin.android.viewmodel.ext.android.viewModel
из зависимости:
implementation "org.koin:koin-android-viewmodel:+" // изменение + на w/e является последним, когда вы читаете это
(ответ, потому что я искал сам, и гугл отправил меня сюда!)
да, очень сложно иметь правильный импорт при использовании koin, но этот вопрос не связан с коином.
Вопрос возник в Google при поиске проблем с Koin (те же симптомы), так что никогда не знаешь :)
Зачем нужен Коин?
Коин имеет тот же API. Так что это не обязательно, это альтернатива с той же проблемой.
Я просто думаю, что вы лучше подтвердите свой ответ, если объясните, почему вы предлагаете монету в самом ответе вместо комментариев.
Вы можете реализовать
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, а не активность
Спасибо, что заметили это!
Я думаю, вам нужна эта зависимость для вашей деятельности, если вы хотите использовать делегирование kotlin для модели представления.
//ViewModels delegation extentensions for activity
implementation 'androidx.activity:activity-ktx:1.3.1'
Спасибо! Это было решением для меня.
Да, это правильный ответ. Спасибо.
Вы можете исправить это, внедрив библиотеку fragment-ktx следующим образом.
def fragment_version = "1.4.0"
implementation("androidx.fragment:fragment-ktx:$fragment_version")
Узнайте больше и проверьте последнюю версию здесь.
Принимает ли ваша ViewModel какой-либо параметр, например репозиторий или базу данных?