skip to Main Content

My viewModel contains some variables such as how many cardViews should be created in the recyclerView. Therefore, I am looking for a way to access 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()

2

Answers


  1. 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
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search