Skip to content

Instantly share code, notes, and snippets.

@Alezhka
Last active July 2, 2018 10:42
Show Gist options
  • Save Alezhka/b36930f4b8a4d75aba6d4ab777cced77 to your computer and use it in GitHub Desktop.
Save Alezhka/b36930f4b8a4d75aba6d4ab777cced77 to your computer and use it in GitHub Desktop.
Dagger2 viewmodel mapping.
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
BuildersModule.class})
public interface AppComponent {
void inject(Application app);
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application app);
AppComponent build();
}
}
@Module(includes = {AndroidInjectionModule.class, ViewModelModule.class})
public class AppModule {
@Provides
Context provideContext(Application application) {
return application.getApplicationContext();
}
@Provides
android.app.Application provideAndroidApplication(Application application) {
return application;
}
}
@Singleton
public class SampleViewModelFactory extends ViewModelProvider.NewInstanceFactory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public SampleViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@NonNull
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(@NonNull 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);
}
}
}
@Module
abstract class BuildersModule {
@ContributesAndroidInjector(modules = {SampleActivityModule.class})
abstract SampleActivity bindSampleActivity();
}
public class SampleActivity extends AppCompatActivity {
@Inject
SampleViewModelFactory viewModelFactory;
private SampleViewModel viewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
viewModel = ViewModelProviders.of(this, viewModelFactory).get(SampleViewModel.class);
}
}
@Module(includes = {InterviewModule.class})
public class SampleActivityModule {
}
public class SampleViewModel extends AndroidViewModel {
@Inject
public InterviewViewModel(@NonNull final Application application) {
super(application);
}
}
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
public @interface ViewModelKey {
Class<? extends ViewModel> value();
}
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(SampleViewModel.class)
abstract ViewModel bindSampleViewModel(SampleViewModel viewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(AppViewModelFactory factory);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment