作者:so直接离我远点儿 | 来源:互联网 | 2023-02-02 15:26
1> 小智..:
你需要实现自己的ViewModelProvider.Factory
.Google创建了一个示例应用,演示如何将Dagger 2与ViewModels连接.链接.你需要这5件事:
在ViewModel中:
@Inject
public UserViewModel(UserRepository userRepository, RepoRepository repoRepository) {
定义注释:
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class extends ViewModel> value();
}
在ViewModelModule中:
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserViewModel.class)
abstract ViewModel bindUserViewModel(UserViewModel userViewModel);
在片段中:
@Inject
ViewModelProvider.Factory viewModelFactory;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);
厂:
@Singleton
public class GithubViewModelFactory implements ViewModelProvider.Factory {
private final Map, Provider> creators;
@Inject
public GithubViewModelFactory(Map, Provider> creators) {
this.creators = creators;
}
@SuppressWarnings("unchecked")
@Override
public T create(Class modelClass) {
Provider extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry, Provider> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
您还必须声明:`@Binds abstract ViewModelProvider.Factory bindViewModelFactory(GithubViewModelFactory factory);`在您的ViewModelModule中
您还需要定义@ViewModelKey https://github.com/googlesamples/android-architecture-components/blob/388a10dd5a814ba6aaa9bf8dee8e7c1c5840b3a5/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelKey.java
欢迎来到Stack Overflow.我们总是欢迎指向潜在解决方案的链接,但请在链接周围添加上下文,以便您的其他用户能够了解它是什么以及它为什么存在.如果目标站点无法访问或永久脱机,请始终引用重要链接的最相关部分.看看[为什么以及如何删除某些答案?](/sf/ask/17360801/)和[我如何写出一个好的答案?](/sf/ask/17360801/ /如何到结果)
我相信此答案中缺少一些内容。我仍然让我的工厂为null,Android退回到默认工厂,并产生“没有零参数构造函数”异常。
2> argenkiwi..:
今天我学会了一种避免为我的ViewModel
课程编写工厂的方法:
class ViewModelFactory @Inject constructor(
private val viewModel: Lazy
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun create(modelClass: Class): T = viewModel.get() as T
}
编辑:正如@Calin在评论中指出的那样,我们Lazy
在上面的代码片段中使用Dagger ,而不是Kotlin的.
ViewModel
您可以将一个泛型ViewModelFactory
注入到您的活动和片段中,而不是注入它,并获取任何实例ViewModel
:
class MyActivity : Activity() {
@Inject
internal lateinit var viewModelFactory: ViewModelFactory
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
this.viewModel = ViewModelProviders.of(this, viewModelFactory)
.get(MyViewModel::class.java)
...
}
...
}
我AndroidInjection.inject(this)
和dagger-android
库一样使用,但您可以按照自己喜欢的方式注入活动或片段.剩下的就是确保您ViewModel
从模块中提供:
@Module
object MyModule {
@JvmStatic
@Provides
fun myViewModel(someDependency: SomeDependency) = MyViewModel(someDependency)
}
或者将@Inject
注释应用于其构造函数:
class MyViewModel @Inject constructor(
someDependency: SomeDependency
) : ViewModel() {
...
}
啊得到它,是匕首懒惰,而不是从kotlin懒惰:(
inline fun
ViewModelFactory .get(activity:FragmentActivity):T = ViewModelProviders.of(activity,this).get(T :: class.java)