Using the google sample GithubsampleBrowser I have become stuck on trying to inject the ViewModelProvider.Factory.
When comparing with the sample, I see it goes GithubViewModelFactory fine but mine never does and i'm not sure what I am missing. Hopefully it is something very simple and presumably is because I am using androidx components instead.
Main Activity:
public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector {
@Inject
DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
return dispatchingAndroidInjector;
}
}
CategoryFragment:
public class CategoryFragment extends Fragment implements Injectable {
@Inject
ViewModelProvider.Factory viewModelFactory;// <-- remains null
AppInjector:
public class AppInjector {
private AppInjector() {}
public static void init(CrosscareApp crossCareApp) {
DaggerAppComponent.builder().application(crossCareApp)
.build().inject(crossCareApp);
crossCareApp
.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
........
}
private static void handleActivity(Activity activity) {
if (activity instanceof HasSupportFragmentInjector) {
AndroidInjection.inject(activity);
}
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentCreated(FragmentManager fm, Fragment f,
Bundle savedInstanceState) {
if (f instanceof Injectable) {
AndroidSupportInjection.inject(f);
}
}
}, true);
}
}
}
AppComponent:
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
MainActivityModule.class
})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(CrosscareApp crosscareApp);
}
AppModule:
@Module(includes = ViewModelModule.class)
class AppModule {
@Singleton @Provides
CrosscareService provideCrossCareService() {
return new Retrofit.Builder()
..........
}
ViewModelModule:
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(CategoryViewModel.class)
abstract ViewModel bindCategoryViewModel(CategoryViewModel categoryViewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(CrosscareViewModelFactory factory);
}
CrosscareViewModel:
@Singleton
public class CrosscareViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public CrosscareViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
Greatly appreciate any help.
Well after all that, I was missing one thing. In the manifest, I needed:
android:name=".CrosscareApp"
In the sample, it was
android:name=".GithubApp"
Presumably the file at the root of the directory.
And then it works.