作者:yeszio | 来源:互联网 | 2022-11-28 08:45
我使用的首选方式在“活动和片段”中注入依赖项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
它们可以按预期工作。
1> Alexandr Sus..:
这是我向BottomSheetDialogFragment()提供ViewModel的方式。首先在MyApp类中设置Dagger。
class MyApp : Application(), HasActivityInjector, HasSupportFragmentInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector
@Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector
override fun onCreate() {
super.onCreate()
initDagger()
}
override fun activityInjector(): AndroidInjector = activityInjector
override fun supportFragmentInjector(): AndroidInjector = 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 {
@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布局
.......
getDataBinding()和getViewModel()是扩展函数
fun Fragment.getDataBinding(inflater: LayoutInflater, @LayoutRes layoutId: Int, container: ViewGroup?): T =
DataBindingUtil.inflate(inflater, layoutId, container, false)
inline fun Fragment.getViewModel(factory: ViewModelProvider.Factory = ViewModelProviders.DefaultFactory(activity!!.application)): T =
ViewModelProviders.of(this, factory).get(T::class.java)