Provider Template - method
@Suppress("UNCHECKED_CAST")
fun <T: ViewModel> VMProvider(
owner: ViewModelStoreOwner,
instance: ViewModel
): T {
val factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return if (modelClass.isAssignableFrom(instance.javaClass)) {
instance as T
} else {
throw IllegalArgumentException()
}
}
}
return ViewModelProvider(owner, factory).get((instance as T).javaClass)
}
// use
val viewModel by lazy {
val tempViewModel = TempViewModel(TempUseCase(TempRepository()))
VMProvider(this@Activity, tempViewModel)
}
Provider Template - member variable
private val viewModel by lazy {
val repository: TempRepository = TempRepositoryImpl()
val factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return TempViewModel(TempUseCase(repository)) as T
}
}
return@lazy ViewModelProvider(this@Activity, factory)[TempViewModel::class.java]
}
Provider Template - class
internal object VieModelFactory {
inline fun <reified VM : ViewModel> getViewModel(
owner: ViewModelStoreOwner,
crossinline creator: () -> VM
): VM {
val factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return creator() as T
}
}
return ViewModelProvider(owner, factory)[VM::class.java]
}
}
// use
val viewModel by lazy {
ViewModelFactory.getViewModel<TempViewModel>(this@Activity) {
TempViewModel(TempUseCase(TempRepository()))
}
}
VM - 제네릭 타입
inline + reified - 컴파일 시 제네릭 타입 정보가 사라지지 않도록 하여 VM::class.java 같은 런타임 타입 참조가 가능 (Kotlin에서 제네릭 타입은 런타임에 타입 소거**)**
crossinline - 람다 내부에서 return 을 못 하게 방지
LiveData for event only
class MutableEventData() : EventLiveData() {
fun notifyEvent() {
super.setValue(true)
}
fun postEvent() {
super.postValue(true)
}
}
open class EventLiveData() : LiveData<Boolean>() {}
// use - ViewModel
private val _sendEvent: MutableEventData = MutableEventData()
val sendEvent: EventLiveData get() = _sendEvent
// use - View
viewModel.sendEvent.observe(this) {
// TODO
}