带柄的android ViewModelFactory [英] android ViewModelFactory with hilt

查看:109
本文介绍了带柄的android ViewModelFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我首先尝试使用android ViewModel Hilt DI

I am first trying android ViewModel and Hilt DI

据我从下面的链接了解,要使用运行时值初始化ViewModel,我应该使用 ViewModelFactory

As i understand from below link, to initialize ViewModel with a value on run-time i should use ViewModelFactory

使用ViewModelFactory

//ViewModel
class ScoreViewModel(finalScore: Int) : ViewModel() {
   // The final score
   var score = finalScore
   init {
       Log.i("ScoreViewModel", "Final score is $finalScore")
   }
}

//ViewModelFactory
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
   if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) {
       return ScoreViewModel(finalScore) as T
   }
   throw IllegalArgumentException("Unknown ViewModel class")
}


//Fragment
viewModelFactory = ScoreViewModelFactory(ScoreFragmentArgs.fromBundle(arguments!!).score)

要使用带有视图柄的ViewModel,我应该使用 @ViewModelInject ,如下面的链接所述

And to use ViewModel with hilt i should use @ViewModelInject as explained in below link

即时通讯和Jetpack集成

//ViewModel
class ExampleViewModel @ViewModelInject constructor(
  private val repository: ExampleRepository,
  @Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
  ...
}

//Activity / Fragment
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
  private val exampleViewModel: ExampleViewModel by viewModels()
  ...
}

但是如何将 Hilt ViewModelFactory 一起使用?

But how to use Hilt with ViewModelFactory?

答案似乎在 @Assisted 中,但是我不知道怎么做

It seems the answer is in the @Assisted but i can't figure out how

如何告诉我我喜欢它向ViewModel注入存储库接口,同时仍然允许ViewModelFactory在运行时使用参数初始化ViewModel?

How to tell hilt i like it to inject repository interfaces to ViewModel while still allowing ViewModelFactory to initialize the ViewModel with parameters on run-time?

推荐答案

由@Elye提供,接下来的文章有很大帮助.我建议阅读.

courtesy of @Elye, next articles helped a lot. I recommend a read.

通过注入将活动意图数据传递给ViewModel

使用Dagger Hilt注入ViewModel

似乎不需要大多数Factory,因为大多数 viewmodel 初始参数取自先前的片段,可以通过 SavedStateHandle 进行访问,如果将其标记为@Assisted,则会自动注入

It seems that mostly Factory is not needed since mostly viewmodel initial parameters are taken from previous fragment and can be accessed via SavedStateHandle which is automatically injected if marked as @Assisted

为了进行设置,我使用了以下代码实验室教程

To set-up hilt i used the following code-labs tutorial

使用击键在您的Android应用中

然后,仅使用下一个代码自动完成 viewModel 注入

Then, viewModel injection is done automatically using only the next code

请注意,正如fabioCollini 此处所述,它似乎是 savedStateHandle 安全参数,代码也可以从安全参数获取值钥匙.实际上,这就是我在以下示例中所做的.ps:为了使安全参数更安全",我确实尝试将 SavedStateHandle 替换为 ItemsFragmentArgs ,希望它能正常工作,但该应用程序无法编译.我希望它会在将来实施(如果已经实现,请告诉我)

Note that as noted by fabioCollini here, it seems savedStateHandle can also get values from safe args by simply placing argument name as the key. In fact, that is what i did in the following example. ps: In an attempt to make the safe args be more "safe", i did try to replace the SavedStateHandle with ItemsFragmentArgs hoping it will work but the app did not compile. I do hope it will be implemented in the future (and if already, please let me know)

//ItemFragment file
@AndroidEntryPoint
class ItemsFragment : Fragment() {

    private val viewModel: ItemsViewModel by viewModels()

    //use viewModel as you would. No need to initialize.
}

//Module file - if you have any repository, remember to bind it 
//or provide the exact implementation as noted in code-labs
@InstallIn(ApplicationComponent::class)
@Module
abstract class DatabaseModuleBinder {

    @Binds
    abstract fun bindGlistRepository(impl: FirestoreGlistRepository): GlistRepository

}


//ItemsViewModel file - lastly, anotate as follows and take your arguments 
//from savedStateHandle (for safe args, use variable name as key)
class ItemsViewModel @ViewModelInject constructor(private val glistRepo: GlistRepository,
                     @Assisted private val savedStateHandle: SavedStateHandle) : ViewModel() {

    private val glistLiveDate = glistRepo.getGlistLiveData(
        savedStateHandle.get<String>("listId")!!
    )

..
}

希望它对任何人都有帮助,如果有任何错误,请告诉我

Hope it helps anyone and if any mistake, please let me know

这篇关于带柄的android ViewModelFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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