Могу ли я управлять владельцем жизненного цикла, вводя viewModel с помощью Koin?

У меня есть одно приложение Activity.

Я хочу привязать viewModel к жизненному циклу родительского фрагмента (FlowFragmentLogin), и поделиться им с дочерними фрагментами (CellFragment, InfoFragment, etc). Так что когда я переезжаю из FlowFragmentLogin в FlowFragmentMain, viewModel onCleared() назывался.

Но единственный способ, который я нашел, - это поделиться viewModel между Activity и его фрагментами: https://insert-koin.io/docs/1.0/documentation/koin-android/index.html

И никакого контроля над владельцами жизненного цикла. Что для меня неприемлемо, хотя бы потому, что эта viewModel будет жить до смерти приложения.

3 ответа

С навигацией 2.1.0-alpha02:

Теперь вы можете создавать ViewModels, которые находятся на уровне навигационного графика, с помощью делегата свойства navGraphViewModels() для пользователей Kotlin или с помощью API-интерфейса getViewModelStore (), добавленного в NavController.

Вы можете найти журнал изменений здесь и документ.

К сожалению, Коин не может поддерживать эту функцию, так как viewModel() или же sharedViewModel() был связан с деятельностью. Но поддержка nav уже запланирована в 2.1.x и вы можете отслеживать здесь.


А пока вот мое решение:

  1. использование navGraphViewModels() вместо viewModel() в коине.
class DetailFr : Fragment() {
    private val vm: DetailViewModel by navGraphViewModels(R.id.main_nav_graph)
}
  1. Сделать ViwModel реализует KoinComponent так что мы можем использовать by inject() вместо того, чтобы вводить с помощью конструктора.
class DetailViewModel : ViewModel(), KoinComponent {

    private val repo: DetailRepository by inject()
    // othetr objects you need
}

Надеюсь, это поможет

Сделать это можно, используя новую версию Koin(2.1.0) и немного магии:)

Все, что вам нужно, это добавить эту функцию расширения:

inline fun <reified VM : ViewModel> Fragment.sharedGraphViewModel(
    @IdRes navGraphId: Int,
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
) = lazy {
    val store = findNavController().getViewModelStoreOwner(navGraphId).viewModelStore
    getKoin().getViewModel(ViewModelParameter(VM::class, qualifier, parameters, null, store, null))
}

И теперь вы можете просто получить свою ViewModel из вложенного графа:

private val viewModel: MyViewModel by sharedGraphViewModel(R.id.my_graph)

В версии для коинов 3.1.3есть новая функция расширения koinNavGraphViewModel.

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

implementation "io.insert-koin:koin-androidx-navigation:$koin_version"

Его можно использовать так

private val viewModel: MyViewModel by koinNavGraphViewModel(R.id.my_graph)

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