如何使用Dagger2将ViewModel注入BottomSheetDialogFragment中?

编码我

我使用的首选方式在“活动和片段”中注入依赖项AndroidInjection.inject(this)我有推荐的ViewmodelFactory注入viewmodel。我的注射工作在“活动和片段”中。但是我遇到了BottomSheetDialogFragment的问题,因为不允许我将BottomSheetDialogFragment指定为this所以我@Inject lateinit var viewModelFactory: ViewModelFactory没有初始化。我相信注入应该是可能的,因为BottomSheetDialogFragment应该是Fragment类的子类,但看起来并非如此。我使用的android.x相信也会引起问题。Dagger还不支持它吗?

我应该以哪种方式实现ViewModelFactory注入?

更新:当我尝试用注入片段时AndroidInjection.inject(this)androidx.fragment.app.Fragment只有不能使用android.app.Fragement我扩展了Fragments,DaggerFragment它们可以按预期工作。

亚历山大·舒什科夫

这是我向BottomSheetDialogFragment()提供ViewModel的方式。首先在MyApp类中设置Dagger。

class MyApp : Application(), HasActivityInjector, HasSupportFragmentInjector {

@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
@Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>

override fun onCreate() {
    super.onCreate()

    initDagger()
}

override fun activityInjector(): AndroidInjector<Activity> = activityInjector

override fun supportFragmentInjector(): AndroidInjector<Fragment> = supportFragmentInjector

private fun initDagger(){
    DaggerAppComponent
        .builder()
        .application(this)
        .build()
        .injectApp(this)
}

然后是AppComponent类

@Singleton
@Component(
modules = [
    AppModule::class,
    UiModule::class,
    AndroidSupportInjectionModule::class,
    AndroidInjectionModule::class
])interface AppComponent : AndroidInjector<MyApp> {

   @Component.Builder
   interface Builder {
       @BindsInstance
       fun application(application: MyApp): Builder

       fun build(): AppComponent
   }

    fun injectApp(app: MyApp)
}

在这里,我们对UiModule :: class感兴趣

@Module
abstract class UiModule {

    @Binds
    abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory

    @PerFragment
    @ContributesAndroidInjector(modules = [(FilterModule::class)])
    abstract fun contributeFilterFragment(): FilterFragment
}

您已经有ViewModelFactory,所以我不粘贴此代码。然后FilterModule

@Module
abstract class FilterModule {

   @Binds
   @IntoMap
   @PerFragment
   @ViewModelKey(FilterViewModel::class)
   abstract fun bindViewModel(viewModel: FilterViewModel): ViewModel
}

最后是FilterFragment和FilterViewModel

class FilterFragment : BottomSheetDialogFragment() {

   @Inject
   lateinit var factory: ViewModelProvider.Factory

   private lateinit var binding: FragmentFilterBinding
   private lateinit var viewModel: FilterViewModel

   override fun onAttach(context: Context?) {
       AndroidSupportInjection.inject(this)
       super.onAttach(context)
   }

   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       binding = getDataBinding(inflater, R.layout.fragment_filter, container)
       viewModel = getViewModel(factory)
       binding.viewModel = viewModel
       return binding.root
   }
}

class FilterViewModel @Inject constructor(private val testUseCase:TestUseCase) : BaseViewModel() {
     //do something
}

fragment_filter布局

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/tools">

<data>

    <variable
        name="viewModel"
        type="com.myapp.presentation.screen.filter.FilterViewModel" />
</data>
   .......

getDataBinding()和getViewModel()是扩展函数

fun <T : ViewDataBinding> Fragment.getDataBinding(inflater: LayoutInflater, @LayoutRes layoutId: Int, container: ViewGroup?): T =
    DataBindingUtil.inflate(inflater, layoutId, container, false)

inline fun <reified T : BaseViewModel> Fragment.getViewModel(factory: ViewModelProvider.Factory = ViewModelProviders.DefaultFactory(activity!!.application)): T =
    ViewModelProviders.of(this, factory).get(T::class.java)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用Dagger2注入ViewModel

如何在Dagger2 android中为ViewModel使用构造函数注入?

如何使用Dagger2将活动注入片段

如何使用Dagger2将依赖项注入任何类型的对象中?

无法使用Dagger2 Android Java注入ViewModel

如何使用Dagger2在ViewModel构造函数中注入WorkManager实例?

使用dagger2将类注入Workmanager(Java)

使用dagger2创建模型时如何将模型注入演示者?

如何使用dagger2将活动注入适配器

如何使用Dagger2注入嵌套类

如何使用Dagger2在服务中注入依赖项

如何使用Dagger2在Android中注入LifecycleOwner?

如何重用Dagger2注入的AsyncTask?

没有@Inject构造函数的ViewModel的Dagger2注入

Dagger2 注入抽象 ViewModel 的特定实例

使用 Dagger 2 将 ViewModel 注入 Fragment,带参数

如何使用Dagger 2在ViewPager中注入相同片段的ViewModel

如何使用Dagger2将FragmentPagerAdapter正确地插入我的活动类中?

在Dagger2中将依赖项注入后台服务

尝试使用Dagger2和Kotlin将ViewModelProvider注入Activity时出错

Dagger2 使用参数注入类(使用 Room)

如何处理应用程序后台以恢复使用 Dagger2 注入的 Exoplayer?

Android espresso-如何使用Dagger2注入依赖项

如何在Android中使用Dagger2依赖注入和Robolectric进行测试?

如何在Android中使用Dagger2轻松注入活动对象?

无法在Java中的Android使用dagger2注入的片段依赖

Kotlin Dagger2中的适配器依赖注入

使用Dagger2进行内部依赖注入

使用 Hilt/Dagger2 注入密封类