fragmentDispatchingAndroidInjector,同时使用支持片段 [英] fragmentDispatchingAndroidInjector while using support fragments

查看:1240
本文介绍了fragmentDispatchingAndroidInjector,同时使用支持片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在使用支持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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆