Estoy tratando de pasar un parámetro de constructor en la clase ViewModel. Pero no entiendo cuál es el mejor enfoque para hacer esto. Por favor, eche un vistazo al código y comente y déjeme saber la manera más fácil y apropiada.
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding // Question 1: How can I pass constructor parameter if I use this delegate feature? // private lateint var viewModel: MainViewModel by viewModels() private lateinit var viewModel: MainViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val repository = Repository() // Passing constructor directly works. viewModel = MainViewModel(repository) // Question 2: Why do I need this factory class / method as it works without these two lines. // val viewModelFactory = MainViewModelFactory(repository) // viewModel = ViewModelProvider(this, viewModelFactory).get(MainViewModel::class.java) viewModel.getPost() viewModel.mResponse.observe(this, Observer { response -> if (response.isSuccessful) { Log.d("Response: ", response.body()?.userId.toString()) Log.d("Response: ", response.body()?.id.toString()) binding.textView.text = response.body()?.title.toString() Log.d("Response: ", response.body()?.body.toString()) } else { Log.d("Response: ", response.errorBody().toString()) binding.textView.text = response.code().toString() } }) } }// Question 1: How can I pass constructor parameter if I use this delegate feature? // private lateint var viewModel: MainViewModel by viewModels() Pasaría su ViewModelFactory como parámetro a viewModels() . O, según la naturaleza del parámetro, utilice un marco de inversión de dependencia (Dagger/Hilt, Koin, etc.). En su caso, parece que está pasando algún tipo de repositorio, en cuyo caso un marco de inversión de dependencia es una solución popular.
// Question 2: Why do I need this factory class / method as it works without these two lines. Porque en realidad no funciona. En particular, esa instancia de MainViewModel no sobrevive a un cambio de configuración (por ejemplo, rotación de pantalla). Si desea utilizar el sistema Jetpack ViewModel correctamente, el sistema ViewModel debe crear una instancia de su MainViewModel .
Aquí hay otro hilo sobre este tema¿Por qué se necesita una fábrica de modelos de vista en Android?
Se usa ViewModelFactory para crear ViewModel si requiere argumentos adicionales más allá del constructor básico.
El propósito es la separación de preocupaciones, no debe instanciar un ViewModel en la Actividad porque entonces la Actividad debe conocer todos los parámetros que requiere el ViewModel. El objetivo es mantener su código de vista lo más tonto posible, por lo que no es una buena idea mantener referencias al código de la capa de datos y la lógica comercial en su actividad. Ej: Repositorio
Además, un ViewModelProvider le permite compartir una sola instancia de un ViewModel entre actividades y fragmentos si lo desea, esto puede permitirle mantener el estado en varios lugares sin pasar datos.
Aquí hay un curso de desarrollo de Android sobre MVVM, incluye una lección sobre cómo usar correctamente ViewModelFactory https://developer.android.com/codelabs/kotlin-android-training-view-model#7