My viewModel contains som variables such as how many cardViews should be created in the recyclerView. Therefore i am looking for at way to acces the same viewModel object in my adapter class. Is there a way to do so or a better alternative? My code is in kotlin
class RecyclerAdapter : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
private val gameViewModel: GameViewModel by activityViewModels()
CodePudding user response:
Your Fragment's views should have a shorter lifecycle than your associated ViewModel, so it should be OK to pass it in as a constructor parameter.
class RecyclerAdapter(private val gameViewModel: GameViewModel) :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
//...
}
Then pass the view model reference in from the Fragment when you instantiate the adapter in onViewCreated()
.
Personally, I wouldn't do this because presumably your ViewModel has lots of stuff in it that is irrelevant to the Adapter. Separation of concerns. I would make parameters only for the properties that are needed and let the Fragment pass them along from the ViewModel.
CodePudding user response:
Since you have provided only 2 lines of code it is hard to know exactly what you are doing wrong.
Normally you would retrieve a ViewModel in an Activity class or a Fragment class like this
class MyActivity /* other stuff */ {
// this line produces/retrieves an instance of GameViewModel
// where its owner is MyActivity
private val gameViewModel: GameViewModel by viewModels()
}
Then somewhere else inside your activity class, you instantiate your RecycleAdapter class. There you would pass the gameViewModel to it. Of course, to be able to do that your RecyclerAdapter would either have to accept a GameViewModel as a constructor parameter, or through a setter, or some other function call.
Here is an example through a constructor parameter. Your RecyclerAdapter class would have to be defined something like this (note that this is Kotlin concise syntax for declaring properties and initializing them from the primary constructor)
class RecyclerAdapter(
private val gameViewModel: GameViewModel,
// add more constructor parameters/class properties here if needed
) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
// other class properties that you don't want to initialize
// through the primary constructor
// ...
// the class body where you implement RecyclerView.Adapter<> methods
// ...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// gameViewModel can be used here
gameViewModel.doSomething()
}
}
And as a last step, modify the line in your code, where you create your RecyclerAdapter instance
// here we create a new RecyclerAdapter and pass the gameViewModel to it
val adapter = RecyclerAdapter(gameViewModel)
recyclerView.adapter = adapter