How can I create ViewModel and inject repository to it with dagger 2?












6















I try understanding ViewModel. I create ViewModel:



public class UsersViewModel extends ViewModel {

private final UsersRepository usersRepository;

public UsersViewModel(UsersRepository usersRepository) {
this.usersRepository = usersRepository;
}

public LiveData<List<User>> loadAll() {
return usersRepository.getAll();
}

}


But I not understand 2 things:




  1. How can I inject UsersRepository to this VievModel? When I used presenter I can create it with dagger 2 like this:



@Module
public class PresentersModule {

@Singleton
@Provides
UsersPresenter provideUsersPresenter(UsersRepository usersRepository) {
return new UsersPresenter(usersRepository);
}
}



but how can I do it with ViewModel? Like this?



@Module
public class ViewModelsModule {

@Singleton
@Provides
UsersViewModel provideUsersViewModel(UsersRepository usersRepository) {
return new UsersViewModel(usersRepository);
}
}




  1. How can I get this ViewModel in fragment? With presenter I can this:



    presenter = MyApplication.get().getAppComponent().getUsersPresenter();












share|improve this question



























    6















    I try understanding ViewModel. I create ViewModel:



    public class UsersViewModel extends ViewModel {

    private final UsersRepository usersRepository;

    public UsersViewModel(UsersRepository usersRepository) {
    this.usersRepository = usersRepository;
    }

    public LiveData<List<User>> loadAll() {
    return usersRepository.getAll();
    }

    }


    But I not understand 2 things:




    1. How can I inject UsersRepository to this VievModel? When I used presenter I can create it with dagger 2 like this:



    @Module
    public class PresentersModule {

    @Singleton
    @Provides
    UsersPresenter provideUsersPresenter(UsersRepository usersRepository) {
    return new UsersPresenter(usersRepository);
    }
    }



    but how can I do it with ViewModel? Like this?



    @Module
    public class ViewModelsModule {

    @Singleton
    @Provides
    UsersViewModel provideUsersViewModel(UsersRepository usersRepository) {
    return new UsersViewModel(usersRepository);
    }
    }




    1. How can I get this ViewModel in fragment? With presenter I can this:



      presenter = MyApplication.get().getAppComponent().getUsersPresenter();












    share|improve this question

























      6












      6








      6


      1






      I try understanding ViewModel. I create ViewModel:



      public class UsersViewModel extends ViewModel {

      private final UsersRepository usersRepository;

      public UsersViewModel(UsersRepository usersRepository) {
      this.usersRepository = usersRepository;
      }

      public LiveData<List<User>> loadAll() {
      return usersRepository.getAll();
      }

      }


      But I not understand 2 things:




      1. How can I inject UsersRepository to this VievModel? When I used presenter I can create it with dagger 2 like this:



      @Module
      public class PresentersModule {

      @Singleton
      @Provides
      UsersPresenter provideUsersPresenter(UsersRepository usersRepository) {
      return new UsersPresenter(usersRepository);
      }
      }



      but how can I do it with ViewModel? Like this?



      @Module
      public class ViewModelsModule {

      @Singleton
      @Provides
      UsersViewModel provideUsersViewModel(UsersRepository usersRepository) {
      return new UsersViewModel(usersRepository);
      }
      }




      1. How can I get this ViewModel in fragment? With presenter I can this:



        presenter = MyApplication.get().getAppComponent().getUsersPresenter();












      share|improve this question














      I try understanding ViewModel. I create ViewModel:



      public class UsersViewModel extends ViewModel {

      private final UsersRepository usersRepository;

      public UsersViewModel(UsersRepository usersRepository) {
      this.usersRepository = usersRepository;
      }

      public LiveData<List<User>> loadAll() {
      return usersRepository.getAll();
      }

      }


      But I not understand 2 things:




      1. How can I inject UsersRepository to this VievModel? When I used presenter I can create it with dagger 2 like this:



      @Module
      public class PresentersModule {

      @Singleton
      @Provides
      UsersPresenter provideUsersPresenter(UsersRepository usersRepository) {
      return new UsersPresenter(usersRepository);
      }
      }



      but how can I do it with ViewModel? Like this?



      @Module
      public class ViewModelsModule {

      @Singleton
      @Provides
      UsersViewModel provideUsersViewModel(UsersRepository usersRepository) {
      return new UsersViewModel(usersRepository);
      }
      }




      1. How can I get this ViewModel in fragment? With presenter I can this:



        presenter = MyApplication.get().getAppComponent().getUsersPresenter();









      android viewmodel dagger-2






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jul 8 '18 at 12:47









      ip696ip696

      1,32321341




      1,32321341
























          2 Answers
          2






          active

          oldest

          votes


















          9














          ViewModel is created via ViewModelProvider that uses a ViewModelFactory to create the instances. You can't inject ViewModels directly, instead you should use a custom factory like below



          @Singleton
          public class DaggerViewModelFactory implements ViewModelProvider.Factory {
          private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

          @Inject
          public DaggerViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
          this.creators = creators;
          }

          @SuppressWarnings("unchecked")
          @Override
          public <T extends ViewModel> T create(Class<T> modelClass) {
          Provider<? extends ViewModel> creator = creators.get(modelClass);
          if (creator == null) {
          for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
          if (modelClass.isAssignableFrom(entry.getKey())) {
          creator = entry.getValue();
          break;
          }
          }
          }
          if (creator == null) {
          throw new IllegalArgumentException("unknown model class " + modelClass);
          }
          try {
          return (T) creator.get();
          } catch (Exception e) {
          throw new RuntimeException(e);
          }
          }
          }


          Then you need a module for the dagger that creates the view model factory and view models itself.



          @Module
          abstract class ViewModelModule {
          @Binds
          abstract ViewModelProvider.Factory bindViewModelFactory(DaggerViewModelFactory factory);

          @Binds
          @IntoMap
          @ViewModelKey(VideoListViewModel.class)
          abstract ViewModel provideVideoListViewModel(VideoListViewModel videoListViewModel);

          @Binds
          @IntoMap
          @ViewModelKey(PlayerViewModel.class)
          abstract ViewModel providePlayerViewModel(PlayerViewModel playerViewModel);

          @Binds
          @IntoMap
          @ViewModelKey(PlaylistViewModel.class)
          abstract ViewModel providePlaylistViewModel(PlaylistViewModel playlistViewModel);

          @Binds
          @IntoMap
          @ViewModelKey(PlaylistDetailViewModel.class)
          abstract ViewModel providePlaylistDetailViewModel(PlaylistDetailViewModel playlistDetailViewModel);
          }


          ViewModelKey file is like this



          @Target({ElementType.METHOD})
          @Retention(RetentionPolicy.RUNTIME)
          @MapKey
          @interface ViewModelKey {
          Class<? extends ViewModel> value();
          }


          Now to get your view model in the activity or fragment simply inject the view model factory and then use that factory to create the view model instances



          public class PlayerActivity extends BaseActivity {
          @Inject DaggerViewModelFactory viewModelFactory;
          PlayerViewModel viewModel;

          @Override
          protected void onCreate(Bundle savedInstanceState) {
          AndroidInjection.inject(this);
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_player);
          viewModel = ViewModelProviders.of(this,viewModelFactory).get(PlayerViewModel.class);

          }


          To inject anything to your ViewModel like the repository simply use Constructor Injection.



          public class PlayerViewModel extends ViewModel {
          private VideoRepository videoRepository;
          private AudioManager audioManager;


          @Inject
          public PlayerViewModel(VideoRepository videoRepository, AudioManager audioManager) {
          this.videoRepository = videoRepository;
          this.audioManager = audioManager;

          }
          }


          Check out the fully working example from here https://github.com/alzahm/VideoPlayer, Also I learned many of the dagger stuff from google samples, you can check them out as well.






          share|improve this answer































            0














            I wrote a library that should make this more straightforward and way cleaner, no multibindings or factory boilerplate needed, while also giving the ability to further parametrise the ViewModel at runtime:
            https://github.com/radutopor/ViewModelFactory



            @ViewModelFactory
            class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() {

            val greeting = MutableLiveData<String>()

            init {
            val user = repository.getUser(userId)
            greeting.value = "Hello, $user.name"
            }
            }


            In the view:



            class UserActivity : AppCompatActivity() {
            @Inject
            lateinit var userViewModelFactory2: UserViewModelFactory2

            override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_user)
            appComponent.inject(this)

            val userId = intent.getIntExtra("USER_ID", -1)
            val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId))
            .get(UserViewModel::class.java)

            viewModel.greeting.observe(this, Observer { greetingText ->
            greetingTextView.text = greetingText
            })
            }
            }





            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51232149%2fhow-can-i-create-viewmodel-and-inject-repository-to-it-with-dagger-2%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              9














              ViewModel is created via ViewModelProvider that uses a ViewModelFactory to create the instances. You can't inject ViewModels directly, instead you should use a custom factory like below



              @Singleton
              public class DaggerViewModelFactory implements ViewModelProvider.Factory {
              private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

              @Inject
              public DaggerViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
              this.creators = creators;
              }

              @SuppressWarnings("unchecked")
              @Override
              public <T extends ViewModel> T create(Class<T> modelClass) {
              Provider<? extends ViewModel> creator = creators.get(modelClass);
              if (creator == null) {
              for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
              if (modelClass.isAssignableFrom(entry.getKey())) {
              creator = entry.getValue();
              break;
              }
              }
              }
              if (creator == null) {
              throw new IllegalArgumentException("unknown model class " + modelClass);
              }
              try {
              return (T) creator.get();
              } catch (Exception e) {
              throw new RuntimeException(e);
              }
              }
              }


              Then you need a module for the dagger that creates the view model factory and view models itself.



              @Module
              abstract class ViewModelModule {
              @Binds
              abstract ViewModelProvider.Factory bindViewModelFactory(DaggerViewModelFactory factory);

              @Binds
              @IntoMap
              @ViewModelKey(VideoListViewModel.class)
              abstract ViewModel provideVideoListViewModel(VideoListViewModel videoListViewModel);

              @Binds
              @IntoMap
              @ViewModelKey(PlayerViewModel.class)
              abstract ViewModel providePlayerViewModel(PlayerViewModel playerViewModel);

              @Binds
              @IntoMap
              @ViewModelKey(PlaylistViewModel.class)
              abstract ViewModel providePlaylistViewModel(PlaylistViewModel playlistViewModel);

              @Binds
              @IntoMap
              @ViewModelKey(PlaylistDetailViewModel.class)
              abstract ViewModel providePlaylistDetailViewModel(PlaylistDetailViewModel playlistDetailViewModel);
              }


              ViewModelKey file is like this



              @Target({ElementType.METHOD})
              @Retention(RetentionPolicy.RUNTIME)
              @MapKey
              @interface ViewModelKey {
              Class<? extends ViewModel> value();
              }


              Now to get your view model in the activity or fragment simply inject the view model factory and then use that factory to create the view model instances



              public class PlayerActivity extends BaseActivity {
              @Inject DaggerViewModelFactory viewModelFactory;
              PlayerViewModel viewModel;

              @Override
              protected void onCreate(Bundle savedInstanceState) {
              AndroidInjection.inject(this);
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_player);
              viewModel = ViewModelProviders.of(this,viewModelFactory).get(PlayerViewModel.class);

              }


              To inject anything to your ViewModel like the repository simply use Constructor Injection.



              public class PlayerViewModel extends ViewModel {
              private VideoRepository videoRepository;
              private AudioManager audioManager;


              @Inject
              public PlayerViewModel(VideoRepository videoRepository, AudioManager audioManager) {
              this.videoRepository = videoRepository;
              this.audioManager = audioManager;

              }
              }


              Check out the fully working example from here https://github.com/alzahm/VideoPlayer, Also I learned many of the dagger stuff from google samples, you can check them out as well.






              share|improve this answer




























                9














                ViewModel is created via ViewModelProvider that uses a ViewModelFactory to create the instances. You can't inject ViewModels directly, instead you should use a custom factory like below



                @Singleton
                public class DaggerViewModelFactory implements ViewModelProvider.Factory {
                private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

                @Inject
                public DaggerViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
                this.creators = creators;
                }

                @SuppressWarnings("unchecked")
                @Override
                public <T extends ViewModel> T create(Class<T> modelClass) {
                Provider<? extends ViewModel> creator = creators.get(modelClass);
                if (creator == null) {
                for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
                if (modelClass.isAssignableFrom(entry.getKey())) {
                creator = entry.getValue();
                break;
                }
                }
                }
                if (creator == null) {
                throw new IllegalArgumentException("unknown model class " + modelClass);
                }
                try {
                return (T) creator.get();
                } catch (Exception e) {
                throw new RuntimeException(e);
                }
                }
                }


                Then you need a module for the dagger that creates the view model factory and view models itself.



                @Module
                abstract class ViewModelModule {
                @Binds
                abstract ViewModelProvider.Factory bindViewModelFactory(DaggerViewModelFactory factory);

                @Binds
                @IntoMap
                @ViewModelKey(VideoListViewModel.class)
                abstract ViewModel provideVideoListViewModel(VideoListViewModel videoListViewModel);

                @Binds
                @IntoMap
                @ViewModelKey(PlayerViewModel.class)
                abstract ViewModel providePlayerViewModel(PlayerViewModel playerViewModel);

                @Binds
                @IntoMap
                @ViewModelKey(PlaylistViewModel.class)
                abstract ViewModel providePlaylistViewModel(PlaylistViewModel playlistViewModel);

                @Binds
                @IntoMap
                @ViewModelKey(PlaylistDetailViewModel.class)
                abstract ViewModel providePlaylistDetailViewModel(PlaylistDetailViewModel playlistDetailViewModel);
                }


                ViewModelKey file is like this



                @Target({ElementType.METHOD})
                @Retention(RetentionPolicy.RUNTIME)
                @MapKey
                @interface ViewModelKey {
                Class<? extends ViewModel> value();
                }


                Now to get your view model in the activity or fragment simply inject the view model factory and then use that factory to create the view model instances



                public class PlayerActivity extends BaseActivity {
                @Inject DaggerViewModelFactory viewModelFactory;
                PlayerViewModel viewModel;

                @Override
                protected void onCreate(Bundle savedInstanceState) {
                AndroidInjection.inject(this);
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_player);
                viewModel = ViewModelProviders.of(this,viewModelFactory).get(PlayerViewModel.class);

                }


                To inject anything to your ViewModel like the repository simply use Constructor Injection.



                public class PlayerViewModel extends ViewModel {
                private VideoRepository videoRepository;
                private AudioManager audioManager;


                @Inject
                public PlayerViewModel(VideoRepository videoRepository, AudioManager audioManager) {
                this.videoRepository = videoRepository;
                this.audioManager = audioManager;

                }
                }


                Check out the fully working example from here https://github.com/alzahm/VideoPlayer, Also I learned many of the dagger stuff from google samples, you can check them out as well.






                share|improve this answer


























                  9












                  9








                  9







                  ViewModel is created via ViewModelProvider that uses a ViewModelFactory to create the instances. You can't inject ViewModels directly, instead you should use a custom factory like below



                  @Singleton
                  public class DaggerViewModelFactory implements ViewModelProvider.Factory {
                  private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

                  @Inject
                  public DaggerViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
                  this.creators = creators;
                  }

                  @SuppressWarnings("unchecked")
                  @Override
                  public <T extends ViewModel> T create(Class<T> modelClass) {
                  Provider<? extends ViewModel> creator = creators.get(modelClass);
                  if (creator == null) {
                  for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
                  if (modelClass.isAssignableFrom(entry.getKey())) {
                  creator = entry.getValue();
                  break;
                  }
                  }
                  }
                  if (creator == null) {
                  throw new IllegalArgumentException("unknown model class " + modelClass);
                  }
                  try {
                  return (T) creator.get();
                  } catch (Exception e) {
                  throw new RuntimeException(e);
                  }
                  }
                  }


                  Then you need a module for the dagger that creates the view model factory and view models itself.



                  @Module
                  abstract class ViewModelModule {
                  @Binds
                  abstract ViewModelProvider.Factory bindViewModelFactory(DaggerViewModelFactory factory);

                  @Binds
                  @IntoMap
                  @ViewModelKey(VideoListViewModel.class)
                  abstract ViewModel provideVideoListViewModel(VideoListViewModel videoListViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlayerViewModel.class)
                  abstract ViewModel providePlayerViewModel(PlayerViewModel playerViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlaylistViewModel.class)
                  abstract ViewModel providePlaylistViewModel(PlaylistViewModel playlistViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlaylistDetailViewModel.class)
                  abstract ViewModel providePlaylistDetailViewModel(PlaylistDetailViewModel playlistDetailViewModel);
                  }


                  ViewModelKey file is like this



                  @Target({ElementType.METHOD})
                  @Retention(RetentionPolicy.RUNTIME)
                  @MapKey
                  @interface ViewModelKey {
                  Class<? extends ViewModel> value();
                  }


                  Now to get your view model in the activity or fragment simply inject the view model factory and then use that factory to create the view model instances



                  public class PlayerActivity extends BaseActivity {
                  @Inject DaggerViewModelFactory viewModelFactory;
                  PlayerViewModel viewModel;

                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                  AndroidInjection.inject(this);
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_player);
                  viewModel = ViewModelProviders.of(this,viewModelFactory).get(PlayerViewModel.class);

                  }


                  To inject anything to your ViewModel like the repository simply use Constructor Injection.



                  public class PlayerViewModel extends ViewModel {
                  private VideoRepository videoRepository;
                  private AudioManager audioManager;


                  @Inject
                  public PlayerViewModel(VideoRepository videoRepository, AudioManager audioManager) {
                  this.videoRepository = videoRepository;
                  this.audioManager = audioManager;

                  }
                  }


                  Check out the fully working example from here https://github.com/alzahm/VideoPlayer, Also I learned many of the dagger stuff from google samples, you can check them out as well.






                  share|improve this answer













                  ViewModel is created via ViewModelProvider that uses a ViewModelFactory to create the instances. You can't inject ViewModels directly, instead you should use a custom factory like below



                  @Singleton
                  public class DaggerViewModelFactory implements ViewModelProvider.Factory {
                  private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

                  @Inject
                  public DaggerViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
                  this.creators = creators;
                  }

                  @SuppressWarnings("unchecked")
                  @Override
                  public <T extends ViewModel> T create(Class<T> modelClass) {
                  Provider<? extends ViewModel> creator = creators.get(modelClass);
                  if (creator == null) {
                  for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
                  if (modelClass.isAssignableFrom(entry.getKey())) {
                  creator = entry.getValue();
                  break;
                  }
                  }
                  }
                  if (creator == null) {
                  throw new IllegalArgumentException("unknown model class " + modelClass);
                  }
                  try {
                  return (T) creator.get();
                  } catch (Exception e) {
                  throw new RuntimeException(e);
                  }
                  }
                  }


                  Then you need a module for the dagger that creates the view model factory and view models itself.



                  @Module
                  abstract class ViewModelModule {
                  @Binds
                  abstract ViewModelProvider.Factory bindViewModelFactory(DaggerViewModelFactory factory);

                  @Binds
                  @IntoMap
                  @ViewModelKey(VideoListViewModel.class)
                  abstract ViewModel provideVideoListViewModel(VideoListViewModel videoListViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlayerViewModel.class)
                  abstract ViewModel providePlayerViewModel(PlayerViewModel playerViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlaylistViewModel.class)
                  abstract ViewModel providePlaylistViewModel(PlaylistViewModel playlistViewModel);

                  @Binds
                  @IntoMap
                  @ViewModelKey(PlaylistDetailViewModel.class)
                  abstract ViewModel providePlaylistDetailViewModel(PlaylistDetailViewModel playlistDetailViewModel);
                  }


                  ViewModelKey file is like this



                  @Target({ElementType.METHOD})
                  @Retention(RetentionPolicy.RUNTIME)
                  @MapKey
                  @interface ViewModelKey {
                  Class<? extends ViewModel> value();
                  }


                  Now to get your view model in the activity or fragment simply inject the view model factory and then use that factory to create the view model instances



                  public class PlayerActivity extends BaseActivity {
                  @Inject DaggerViewModelFactory viewModelFactory;
                  PlayerViewModel viewModel;

                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                  AndroidInjection.inject(this);
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_player);
                  viewModel = ViewModelProviders.of(this,viewModelFactory).get(PlayerViewModel.class);

                  }


                  To inject anything to your ViewModel like the repository simply use Constructor Injection.



                  public class PlayerViewModel extends ViewModel {
                  private VideoRepository videoRepository;
                  private AudioManager audioManager;


                  @Inject
                  public PlayerViewModel(VideoRepository videoRepository, AudioManager audioManager) {
                  this.videoRepository = videoRepository;
                  this.audioManager = audioManager;

                  }
                  }


                  Check out the fully working example from here https://github.com/alzahm/VideoPlayer, Also I learned many of the dagger stuff from google samples, you can check them out as well.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jul 8 '18 at 13:46









                  RezaReza

                  1,70921939




                  1,70921939

























                      0














                      I wrote a library that should make this more straightforward and way cleaner, no multibindings or factory boilerplate needed, while also giving the ability to further parametrise the ViewModel at runtime:
                      https://github.com/radutopor/ViewModelFactory



                      @ViewModelFactory
                      class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() {

                      val greeting = MutableLiveData<String>()

                      init {
                      val user = repository.getUser(userId)
                      greeting.value = "Hello, $user.name"
                      }
                      }


                      In the view:



                      class UserActivity : AppCompatActivity() {
                      @Inject
                      lateinit var userViewModelFactory2: UserViewModelFactory2

                      override fun onCreate(savedInstanceState: Bundle?) {
                      super.onCreate(savedInstanceState)
                      setContentView(R.layout.activity_user)
                      appComponent.inject(this)

                      val userId = intent.getIntExtra("USER_ID", -1)
                      val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId))
                      .get(UserViewModel::class.java)

                      viewModel.greeting.observe(this, Observer { greetingText ->
                      greetingTextView.text = greetingText
                      })
                      }
                      }





                      share|improve this answer






























                        0














                        I wrote a library that should make this more straightforward and way cleaner, no multibindings or factory boilerplate needed, while also giving the ability to further parametrise the ViewModel at runtime:
                        https://github.com/radutopor/ViewModelFactory



                        @ViewModelFactory
                        class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() {

                        val greeting = MutableLiveData<String>()

                        init {
                        val user = repository.getUser(userId)
                        greeting.value = "Hello, $user.name"
                        }
                        }


                        In the view:



                        class UserActivity : AppCompatActivity() {
                        @Inject
                        lateinit var userViewModelFactory2: UserViewModelFactory2

                        override fun onCreate(savedInstanceState: Bundle?) {
                        super.onCreate(savedInstanceState)
                        setContentView(R.layout.activity_user)
                        appComponent.inject(this)

                        val userId = intent.getIntExtra("USER_ID", -1)
                        val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId))
                        .get(UserViewModel::class.java)

                        viewModel.greeting.observe(this, Observer { greetingText ->
                        greetingTextView.text = greetingText
                        })
                        }
                        }





                        share|improve this answer




























                          0












                          0








                          0







                          I wrote a library that should make this more straightforward and way cleaner, no multibindings or factory boilerplate needed, while also giving the ability to further parametrise the ViewModel at runtime:
                          https://github.com/radutopor/ViewModelFactory



                          @ViewModelFactory
                          class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() {

                          val greeting = MutableLiveData<String>()

                          init {
                          val user = repository.getUser(userId)
                          greeting.value = "Hello, $user.name"
                          }
                          }


                          In the view:



                          class UserActivity : AppCompatActivity() {
                          @Inject
                          lateinit var userViewModelFactory2: UserViewModelFactory2

                          override fun onCreate(savedInstanceState: Bundle?) {
                          super.onCreate(savedInstanceState)
                          setContentView(R.layout.activity_user)
                          appComponent.inject(this)

                          val userId = intent.getIntExtra("USER_ID", -1)
                          val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId))
                          .get(UserViewModel::class.java)

                          viewModel.greeting.observe(this, Observer { greetingText ->
                          greetingTextView.text = greetingText
                          })
                          }
                          }





                          share|improve this answer















                          I wrote a library that should make this more straightforward and way cleaner, no multibindings or factory boilerplate needed, while also giving the ability to further parametrise the ViewModel at runtime:
                          https://github.com/radutopor/ViewModelFactory



                          @ViewModelFactory
                          class UserViewModel(@Provided repository: Repository, userId: Int) : ViewModel() {

                          val greeting = MutableLiveData<String>()

                          init {
                          val user = repository.getUser(userId)
                          greeting.value = "Hello, $user.name"
                          }
                          }


                          In the view:



                          class UserActivity : AppCompatActivity() {
                          @Inject
                          lateinit var userViewModelFactory2: UserViewModelFactory2

                          override fun onCreate(savedInstanceState: Bundle?) {
                          super.onCreate(savedInstanceState)
                          setContentView(R.layout.activity_user)
                          appComponent.inject(this)

                          val userId = intent.getIntExtra("USER_ID", -1)
                          val viewModel = ViewModelProviders.of(this, userViewModelFactory2.create(userId))
                          .get(UserViewModel::class.java)

                          viewModel.greeting.observe(this, Observer { greetingText ->
                          greetingTextView.text = greetingText
                          })
                          }
                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 21 '18 at 18:10

























                          answered Nov 21 '18 at 18:03









                          Radu ToporRadu Topor

                          1,046610




                          1,046610






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51232149%2fhow-can-i-create-viewmodel-and-inject-repository-to-it-with-dagger-2%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                              ComboBox Display Member on multiple fields

                              Is it possible to collect Nectar points via Trainline?