当前位置: 首页 > 知识库问答 >
问题:

匕首2,底部导航和注射

乐正宏深
2023-03-14

我正在MVVM和Dagger 2中制作小型Android应用程序。但是我不知道如何正确使用Dagger 2,以防我有一个活动和两个片段。这两个片段都是ViewModels的所有者。我已经将ViewModelProvider注入了片段,但我仍然对这个解决方案感到困惑。也许有人会改进我的代码?

活动:

public class MainActivity extends DaggerAppCompatActivity {

private static final String TAG = "MainActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    BottomNavigationView navView = findViewById(R.id.nav_view);

    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupWithNavController(navView, navController);
}

}

第一个片段:

public class EventsFragment extends DaggerFragment {

private static final String TAG = "EventsFragment";
private EventsViewModel eventsViewModel;
private final EventsAdapter adapter = new EventsAdapter();
private List<Event> events = new ArrayList<>();

@Inject
ViewModelProviderFactory viewModelProviderFactory;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    eventsViewModel = ViewModelProviders.of(this, viewModelProviderFactory).get(EventsViewModel.class);
    View root = inflater.inflate(R.layout.fragment_events, container, false);

    RecyclerView recyclerView = root.findViewById(R.id.events_recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setHasFixedSize(true);
    recyclerView.setAdapter(adapter);

    getEvents();

    return root;
}

第二个片段:

public class ScheduleFragment extends DaggerFragment {

private ScheduleViewModel scheduleViewModel;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    scheduleViewModel = ViewModelProviders.of(this).get(ScheduleViewModel.class);
    View root = inflater.inflate(R.layout.fragment_schedule, container, false);

    return root;
}

@Override
public void onAttach(Context context) {
    AndroidSupportInjection.inject(this);
    super.onAttach(context);
}
}

在这种情况下,两个片段都可以工作,但我只能在其中一个片段中注入ViewModelFactory。如果我将其注入第二个:错误:找不到符号类DaggerAppComponent

ActivityBuilders模块:

@Module
public abstract class ActivityBuildersModule {

@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract MainActivity contributeMainActivity();
}

应用组件:

   @Singleton
   @Component(
    modules = {
            AndroidSupportInjectionModule.class,
            ActivityBuildersModule.class,
            AppModule.class,
            ViewModelFactoryModule.class
    }
    )
    public interface AppComponent extends AndroidInjector<BaseApplication> {

@Component.Builder
interface Builder {

    @BindsInstance
    Builder application(Application application);

    AppComponent build();
}

}

FragmentBuilders模块:

 @Module
 public abstract class FragmentBuildersModule {

@ContributesAndroidInjector(
        modules = {ViewModelModule.class, EventsModule.class}
)
abstract EventsFragment contributeEventsFragment();

@ContributesAndroidInjector(
        modules = {ViewModelModule.class}
)
abstract ScheduleFragment contributeScheduleFragment();
}

ViewModelFactory:

@Module
public abstract class ViewModelFactoryModule {

@Binds
public abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelProviderFactory modelProviderFactory);
}

ViewModelKey:

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

ViewModelModule:

@Module

公共抽象类ViewModelModule{

@Binds
@IntoMap
@ViewModelKey(EventsViewModel.class)
public abstract ViewModel bindEventsViewModel(EventsViewModel eventsViewModel);

@Binds
@IntoMap
@ViewModelKey(ScheduleViewModel.class)
public abstract ViewModel bindScheduleViewmodel(ScheduleViewModel scheduleViewModel);

基本应用程序:

public class BaseApplication extends DaggerApplication {


@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
    return DaggerAppComponent.builder().application(this).build();
}

共有1个答案

狄高畅
2023-03-14

就像第一个片段一样试试这个



public class ScheduleFragment extends DaggerFragment {

private ScheduleViewModel scheduleViewModel;

@Inject
ViewModelProviderFactory viewModelProviderFactory;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    scheduleViewModel = ViewModelProviders.of(this, viewModelProviderFactory).get(ScheduleViewModel.class);
    View root = inflater.inflate(R.layout.fragment_schedule, container, false);

    return root;
}
}

也是一种通过在AppModule中添加这样的方法来提供Api的方法

@Singleton
    @Provides
    public RemoteApi provideRemoteApi(){
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(Constants.API_BASE_URL)
            .build()
            .create(RemoteApi::class.java)
    }

在这里,您应该用Api类替换RemoteApi。

 类似资料:
  • 我正在尝试为我的navControl ler提供匕首柄。但是我使用的方法不起作用。我想提供navControl ler以便通过构造函数注入将其注入我的片段中。 我还创建了FragmentWorks类,以便通过构造函数注入我的依赖项。我知道是这里的问题,但我不知道正确的解决方案… 感谢您的帮助,谢谢! 原因:java.lang.ClassCastException:com.example.app。应

  • 嗨,我试图找出如何做一个干净的第三方注入。我想把奥托巴士适当地注入我的服务和活动中。我看到你可以在构造函数上使用inject,但是由于我没有任何Android构造函数,我想知道我如何才能inject我的总线。 Iv创建了一个模块,该模块提供了总线的新实例。Iv还创建了一个组件,该组件具有总线对象的接口。 但是我如何才能得到这个注入,我应该在哪里启动我的图表? 我想做的就是: 我看了这个例子(htt

  • 实现tabbar建议采用小程序原生的tabbar,通过设置page/main.js(即对应小程序中app.json)来实现,详情请看小程序文档。示例如下,仅作参考: tabBar: { color: '#999999', selectedColor: '#1AAD16', backgroundColor: '#ffffff', borderStyle: 'white', /*

  • 这很好,但是如果我使用全局组件甚至子组件中的一个模块,那么应该传入上下文。因此,这意味着如果我用匕首注入演示器,它将被绑定到ApplicationContext。这使得作为JUnit进行测试变得困难。Android代码不应该在演示器中。 所以我想问的是,最好的做法是只在活动、片段、广播接收器和服务中使用匕首吗?就mvp架构而言,这就是。另一个解决方案是设计另一个dagger组件,但不是与appco

  • 在一个android、kotlin项目中,看到这个< code>@set:Inject,但找不到一个好的解释。有人知道吗?

  • Dagger 2即将面世,但可用的示例甚至无法立即编译,文档是Dagger 1的复制粘贴替换。 有没有人有一个在谷歌的Dagger 2上运行的正确应用程序的例子?