Koin with ViewModel

Architecture Components with Koin: ViewModel

Gradle setup

Choose the koin-android-viewmodel dependency to add to your Gradle project (android or androix version):

1
2
3
4
5
6
7
8
9
10
// Add Jcenter to your repositories if needed
repositories {
jcenter()
}
dependencies {
// ViewModel for Android
implementation 'org.koin:koin-android-viewmodel:2.0.0-beta-4'
// or ViewModel for AndroidX
implementation 'org.koin:koin-androidx-viewmodel:2.0.0-beta-4'
}

ViewModel DSL

The koin-android-viewmodel introduces a new viewModel DSL keyword that comes in complement of single and factory, to help declare a ViewModel component and bind it to an Android Component lifecycle.

1
2
3
4
5
6
7
8
val appModule = module {

// ViewModel for Detail View
viewModel { DetailViewModel(get(), get()) }
// or
viewModel<DetailViewModel>()

}

Your declared component must at least extends the android.arch.lifecycle.ViewModel class. You can specify how you inject the constructor of the class and use the get() function to inject dependencies.

The viewModel keyword helps declaring a factory instance of ViewModel. This instance will be handled by internal ViewModelFactory and reattach ViewModel instance if needed.

The viewModel keyword can also let you use the injection parameters.

Injecting your ViewModel

To inject a ViewModel in an Activity, Fragment or Service use:

  • by viewModel() - lazy delegate property to inject a ViewModel into a property

  • getViewModel() - directly get the ViewModel instance

1
2
3
4
5
class DetailActivity : AppCompatActivity() {

// Lazy inject ViewModel
val detailViewModel: DetailViewModel by viewModel()
}

Shared ViewModel

One ViewModel instance can be shared between Fragments and their host Activity.

To inject a shared ViewModel in a Fragment use:

  • by sharedViewModel() - lazy delegate property to inject shared ViewModel instance into a property

  • getSharedViewModel() - directly get the shared ViewModel instance

Just declare the ViewModel only once:

1
2
3
4
5
6
7
val weatherAppModule = module {

// WeatherViewModel declaration for Weather View components
viewModel { WeatherViewModel(get(), get()) }
// or
viewModel<WeatherViewModel>()
}

And reuse it in Activity and Fragments:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class WeatherActivity : AppCompatActivity() {

/*
* Declare WeatherViewModel with Koin and allow constructor dependency injection
*/
private val weatherViewModel by viewModel<WeatherViewModel>()
}

class WeatherHeaderFragment : Fragment() {

/*
* Declare shared WeatherViewModel with WeatherActivity
*/
private val weatherViewModel by sharedViewModel<WeatherViewModel>()
}

class WeatherListFragment : Fragment() {

/*
* Declare shared WeatherViewModel with WeatherActivity
*/
private val weatherViewModel by sharedViewModel<WeatherViewModel>()
}

ViewModel and injection parameters

the viewModel keyword and injection API is compatible with injection parameters.

In the module:

1
2
3
4
5
val appModule = module {

// ViewModel for Detail View with id as parameter injection
viewModel { (id : String) -> DetailViewModel(id, get(), get()) }
}

From the injection call site:

1
2
3
4
5
6
7
class DetailActivity : AppCompatActivity() {

val id : String // id of the view

// Lazy inject ViewModel with id parameter
val detailViewModel: DetailViewModel by viewModel{ parametersOf(id)}
}

that’s all, thanks for your reading.

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!