fragmentDispatchingAndroidInjector,同时使用支持片段 [英] fragmentDispatchingAndroidInjector while using support fragments
问题描述
我试图在使用支持v4碎片的同时创建一个简单的匕首2应用程序。
修改我的应用程序后,我得到了这个奇怪的编译错误:
$ p $ Error:(35,8)error:[dagger .android.AndroidInjector.inject(T)] java.util.Map< java.lang.Class<?扩展了android.support.v4.app.Fragment>,javax.inject.Provider< dagger.android.AndroidInjector.Factory< ;?扩展android.support.v4.app.Fragment>>>不能提供@提供注释的方法。
java.util.Map< java.lang.Class<?扩展了android.support.v4.app.Fragment>,javax.inject.Provider< dagger.android.AndroidInjector.Factory< ;?扩展android.support.v4.app.Fragment>>>注入
dagger.android.DispatchingAndroidInjector。< init>(injectorFactories)
dagger.android.DispatchingAndroidInjector< android.support.v4.app.Fragment>注入
app.series.com.tvshowsapplication.ui.main.MainActivity.fragmentDispatchingAndroidInjector
app.series.com.tvshowsapplication.ui.main.MainActivity注入
dagger.android。 AndroidInjector.inject(arg0)
经过快速搜索,我发现这个链接。它说我需要使用
事情是我不明白我应该在哪里放置这部分
@Multibinds
抽象映射< Class<?扩展android.app.Fragment> ;, AndroidInjector.Factory< ;?扩展android.app.Fragment>> bindNativeFragments();
我猜我需要将它放在BaseActivity中,因为它是一个抽象函数,但我该如何实现它在主要活动中?
My MainActivity:
public class MainActivity扩展BaseActivity< ActivityMainBinding,MainViewModel>实现MainNavigator,HasSupportFragmentInjector {
@Inject
ViewModelProvider.Factory mViewModelFactory;
@Inject
DispatchingAndroidInjector< Fragment> fragmentDispatchingAndroidInjector;
私人MainViewModel mMainViewModel;
私人DrawerLayout mDrawer;
私人工具栏mToolbar;
私人NavigationView mNavigationView;
//私有SwipePlaceHolderView mCardsContainerView;
ActivityMainBinding mActivityMainBinding;
public static Intent getStartIntent(Context context){
Intent intent = new Intent(context,MainActivity.class);
返回意图;
}
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mActivityMainBinding = getViewDataBinding();
mMainViewModel.setNavigator(this);
setUp();
@Override
protected void onResume(){
super.onResume();
if(mDrawer!= null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
public void onFragmentDetached(String tag){
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if(fragment!= null){
fragmentManager
.beginTransaction()
.disallowAddToBackStack()
.setCustomAnimations(R.anim.slide_left,R.anim。 slide_right)
.remove(fragment)
.commitNow();
unlockDrawer();
private void setUp(){
mDrawer = mActivityMainBinding.drawerView;
mToolbar = mActivityMainBinding.toolbar;
mNavigationView = mActivityMainBinding.navigationView;
// mCardsContainerViewerView = mActivityMainBinding.cardsContainer;
setSupportActionBar(mToolbar);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawer,
mToolbar,
R.string.open_drawer,
R.string.close_drawer){
@Override
public void onDrawerOpened(View drawerView){
super.onDrawerOpened(drawerView);
hideKeyboard();
}
@Override
public void onDrawerClosed(View drawerView){
super.onDrawerClosed(drawerView);
}
};
mDrawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
setupNavMenu();
String version = getString(R.string.version)++ BuildConfig.VERSION_NAME;
mMainViewModel.updateAppVersion(version);
mMainViewModel.onNavMenuCreated();
// setupCardContainerView();
subscribeToLiveData();
private void subscribeToLiveData(){
$ b private void setupNavMenu(){
NavHeaderMainBinding navHeaderMainBinding = DataBindingUtil.inflate(getLayoutInflater(),
R.layout.nav_header_main,mActivityMainBinding.navigationView,false);
mActivityMainBinding.navigationView.addHeaderView(navHeaderMainBinding.getRoot());
navHeaderMainBinding.setViewModel(mMainViewModel);
mNavigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item){
mDrawer.closeDrawer (GravityCompat.START);
switch(item.getItemId()){
// case R.id.navItemAbout:
// showAboutFragment();
// return true ;
// case R.id.navItemRateUs:
// RateUsDialog.newInstance()。show(getSupportFragmentManager());
//返回true;
// case R .id.navItemFeed:
// startActivity(FeedActivity.getStartIntent(MainActivity.this));
//返回true;
// case R.id.navItemLogout:
// mMainViewModel.logout();
//返回true;
//默认值:
//返回false;
}
返回false;
}
});
}
// private void showAboutFragment(){
// lockDrawer();
// getSupportFragmentManager()
// .beginTransaction()
// .disallowAddToBackStack()
// .setCustomAnimations(R.anim.slide_left,R.anim.slide_right)
// .add(R.id.clRootView,AboutFragment.newInstance(),AboutFragment.TAG)
// .commit();
//
private void lockDrawer(){
if(mDrawer!= null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
$ b $ private void unlockDrawer(){
if(mDrawer!= null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
@Override
public void openLoginActivity(){
startActivity(LoginActivity.getStartIntent(this));
finish();
$ b @Override
public void handleError(Throwable throwable){
//处理错误
}
@Override
public MainViewModel getViewModel(){
mMainViewModel = ViewModelProviders.of(this,mViewModelFactory).get(MainViewModel.class);
return mMainViewModel;
}
@Override
public int getBindingVariable(){
return BR.viewModel;
}
@Override
public int getLayoutId(){
return R.layout.activity_main;
}
@Override
public AndroidInjector< Fragment> supportFragmentInjector(){
return fragmentDispatchingAndroidInjector;
$ b 更新
我实际上在组件类中添加了模块,这里是我的AppComponent
@Singleton
@组件(modules = {AndroidInjectionModule.class,AppModule.class,ActivityBuilder.class})
public interface AppComponent {
@ Component.Builder $ b $ interface Builder {
@BindsInstance
Builder应用程序(应用程序应用程序);
AppComponent build();
}
void inject(TVShowsApp应用程序);
$ b
AppModule
@Module
public class AppModule {
@Provides
@Singleton
Context provideContext(Application application){
返回应用程序;
$ b @Provides
@Singleton
CalligraphyConfig providesCalligraphyDefaultConfig(){
返回新的CalligraphyConfig.Builder()
。 setDefaultFontPath(fonts / source-sans-pro / SourceSansPro-Regular.ttf)
.setFontAttrId(R.attr.fontPath)
.build();
$ / code $ / pre
和ActivityBuilder
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = MainActivityModule.class)
抽象MainActivity bindMainActivity ();
解决方案因为Dagger已经拥有了 AndroidInjectionModule
(或者<$ c $),所以你可以在你的Component中注册一个模块,但是你不必手动声明它。您可以使用
您可以在官方文档,或者在有关当你需要安装模块时,最近才被问到。
你没有显示你的AppComponent,但你最可能只是忘了添加模块,所以你可以通过将错误添加到组件中来修复错误。
//以某种方式添加它像这样
@Component(modules = {AndroidSupportInjectionModule.class,AppMod ule.class})
public interface AppComponent {
void inject(App app);
}
I'm trying to create a simple dagger 2 application while using support v4 fragments.
After I modified my application I got this strange compilation error
Error:(35, 8) error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method.
java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> is injected at
dagger.android.DispatchingAndroidInjector.<init>(injectorFactories)
dagger.android.DispatchingAndroidInjector<android.support.v4.app.Fragment> is injected at
app.series.com.tvshowsapplication.ui.main.MainActivity.fragmentDispatchingAndroidInjector
app.series.com.tvshowsapplication.ui.main.MainActivity is injected at
dagger.android.AndroidInjector.inject(arg0)
After a quick search I found this link. It says I would need to use
The thing is I didn't understand where should I need to put this part
@Multibinds
abstract Map<Class<? extends android.app.Fragment>, AndroidInjector.Factory<? extends android.app.Fragment>> bindNativeFragments();
My guess I need to put it in BaseActivity because it's an abstract function, but how do I implement it in the main activity?
My MainActivity:
public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> implements MainNavigator, HasSupportFragmentInjector {
@Inject
ViewModelProvider.Factory mViewModelFactory;
@Inject
DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;
private MainViewModel mMainViewModel;
private DrawerLayout mDrawer;
private Toolbar mToolbar;
private NavigationView mNavigationView;
// private SwipePlaceHolderView mCardsContainerView;
ActivityMainBinding mActivityMainBinding;
public static Intent getStartIntent(Context context) {
Intent intent = new Intent(context, MainActivity.class);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityMainBinding = getViewDataBinding();
mMainViewModel.setNavigator(this);
setUp();
}
@Override
protected void onResume() {
super.onResume();
if (mDrawer != null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
public void onFragmentDetached(String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
fragmentManager
.beginTransaction()
.disallowAddToBackStack()
.setCustomAnimations(R.anim.slide_left, R.anim.slide_right)
.remove(fragment)
.commitNow();
unlockDrawer();
}
}
private void setUp() {
mDrawer = mActivityMainBinding.drawerView;
mToolbar = mActivityMainBinding.toolbar;
mNavigationView = mActivityMainBinding.navigationView;
// mCardsContainerViewerView = mActivityMainBinding.cardsContainer;
setSupportActionBar(mToolbar);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawer,
mToolbar,
R.string.open_drawer,
R.string.close_drawer) {
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
hideKeyboard();
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
setupNavMenu();
String version = getString(R.string.version) + " " + BuildConfig.VERSION_NAME;
mMainViewModel.updateAppVersion(version);
mMainViewModel.onNavMenuCreated();
// setupCardContainerView();
subscribeToLiveData();
}
private void subscribeToLiveData() {
}
private void setupNavMenu() {
NavHeaderMainBinding navHeaderMainBinding = DataBindingUtil.inflate(getLayoutInflater(),
R.layout.nav_header_main, mActivityMainBinding.navigationView, false);
mActivityMainBinding.navigationView.addHeaderView(navHeaderMainBinding.getRoot());
navHeaderMainBinding.setViewModel(mMainViewModel);
mNavigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawer.closeDrawer(GravityCompat.START);
switch (item.getItemId()) {
// case R.id.navItemAbout:
// showAboutFragment();
// return true;
// case R.id.navItemRateUs:
// RateUsDialog.newInstance().show(getSupportFragmentManager());
// return true;
// case R.id.navItemFeed:
// startActivity(FeedActivity.getStartIntent(MainActivity.this));
// return true;
// case R.id.navItemLogout:
// mMainViewModel.logout();
// return true;
// default:
// return false;
}
return false;
}
});
}
// private void showAboutFragment() {
// lockDrawer();
// getSupportFragmentManager()
// .beginTransaction()
// .disallowAddToBackStack()
// .setCustomAnimations(R.anim.slide_left, R.anim.slide_right)
// .add(R.id.clRootView, AboutFragment.newInstance(), AboutFragment.TAG)
// .commit();
// }
private void lockDrawer() {
if (mDrawer != null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
private void unlockDrawer() {
if (mDrawer != null)
mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
@Override
public void openLoginActivity() {
startActivity(LoginActivity.getStartIntent(this));
finish();
}
@Override
public void handleError(Throwable throwable) {
// handle error
}
@Override
public MainViewModel getViewModel() {
mMainViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MainViewModel.class);
return mMainViewModel;
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.activity_main;
}
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return fragmentDispatchingAndroidInjector;
}
}
UPDATE
I actually added the module in the component class, here is my AppComponent
@Singleton
@Component(modules = {AndroidInjectionModule.class, AppModule.class, ActivityBuilder.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(TVShowsApp app);
}
AppModule
@Module
public class AppModule {
@Provides
@Singleton
Context provideContext(Application application) {
return application;
}
@Provides
@Singleton
CalligraphyConfig provideCalligraphyDefaultConfig() {
return new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/source-sans-pro/SourceSansPro-Regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build();
}
}
and ActivityBuilder
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity bindMainActivity();
}
解决方案 You need to put it in a module that you then register in your Component, but you don't have to declare it manually, as Dagger already has the AndroidInjectionModule
(or AndroidSupportInjectionModule
with AppCompat) which you can use.
You can find more about the Android setup in the official documentation or see some additional information in a similar question about when you need to install the module that was asked quite recently.
You're not showing your AppComponent, but you most likely just forgot to add the module, so you can fix your error by adding it to your component.
// add it somehow like this
@Component(modules = { AndroidSupportInjectionModule.class, AppModule.class })
public interface AppComponent {
void inject(App app);
}
这篇关于fragmentDispatchingAndroidInjector,同时使用支持片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!