지식쌓기

ViewModel 생성

바나나쥬스 2021. 9. 7. 13:30

dependencies

implementation "androidx.fragment:fragment-ktx:$rootProject.fragmentVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"

 

ViewModel을 생성하는 법

1. 파라미터가 없는 ViewModel

class MyViewModel : ViewModel() {
}

val model: MyViewModel by viewModels()

val model: MyViewModel = ViewModelProvider(this).get(MyViewModel::class.java)

val model: MyViewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)

// custom Factory
class MyViewModelFactory: ViewModelProvider.Factory {
	override fun <T: ViewModel?> create(modelClass: Class<T>):T {
    	return if(modelClass.isAssignableFrom(MyViewModel::class.java)) {
        	MyViewModel() as T
        } else {
        	thorw IllegalArgumentException()
        }
    }
}
val model: MyViewModel = ViewModelProvider(this, MyViewModelFactory()).get(MyViewModel::class.java)

* by viewModels() : ViewModelProvider를 사용하지 않고 ViewModel을 지연생성 (kotlin 코드)

 

2. 파라미터가 있는 ViewModel

class MyViewModel(val param:String) : ViewModel()

// factory 
class MyViewModelFactory(private val param: String) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            MyViewModel(param) as T
        } else {
            throw IllegalArgumentException()
        }
    }
}

val param = "param"
val viewModel:MyViewModel = ViewModelProvider(this, MyViewModelFactory(param)).get(MyViewModel::class.java)

 

dagger를 사용할경우

@InstallIn(ActivityComponent::class)
@Module
interface AssistedInjectModule
class MyViewModel @AssistedInject constructor(
    @Assisted("param") param: String,
) : ViewModel() {

    @AssistedFactory
    interface AssistedViewModelFactory {
        fun create(
            @Assisted("param") param: String,
        ): MyViewModel
    }

    companion object {

        fun provideFactory(
            assistedFactory: MyViewModel.AssistedViewModelFactory,
            param: String,
        ): ViewModelProvider.Factory = object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                return assistedFactory.create(param) as T
            }
        }
    }
}
@Inject 
lateinit var viewModelAssistedFactory: MyViewModel.AssistedViewModelFactory
    

val factory = MyViewModel.provideFactory(viewModelAssistedFactory, "param")
viewModel = ViewModelProvider(
				requireActivity().viewModelStore, factory,
			).get(MyViewModel::class.java)