是否可以在没有工厂的情况下在公共方法中将id参数传递给AndroidViewModel?
我在看Android架构组件示例中的BasicSample应用程序。在ProductViewModel.java文件中,一些注释如下: 不是 在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递 根据我对评论的理解,我想知道是否有可能在不使用工厂的情况下将productId传递给ProductViewModel,以及如何做到这一点 我已经实现了转换,我知道我可以使用switchMap传递productId。但是我正在寻找一种用单个id初始化模型的方法是否可以在没有工厂的情况下在公共方法中将id参数传递给AndroidViewModel?,android,android-architecture-components,Android,Android Architecture Components,我在看Android架构组件示例中的BasicSample应用程序。在ProductViewModel.java文件中,一些注释如下: 不是 在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递 根据我对评论的理解,我想知道是否有可能在不使用工厂的情况下将productId传递给ProductViewModel,以及如何做到这一点 我已经实现了转换,我知道我可以使用switchMap传递productId。但是我正在寻找一种用单个id初始化模型的方法 public class Produ
public class ProductViewModel extends AndroidViewModel {
private final LiveData<ProductEntity> mObservableProduct;
public ObservableField<ProductEntity> product = new ObservableField<>();
private final int mProductId;
private final LiveData<List<CommentEntity>> mObservableComments;
public ProductViewModel(@NonNull Application application, DataRepository repository,
final int productId) {
super(application);
mProductId = productId;
mObservableComments = repository.loadComments(mProductId);
mObservableProduct = repository.loadProduct(mProductId);
}
公共类ProductViewModel扩展了AndroidViewModel{
私有最终LiveData mObservableProduct;
公共ObservableField product=新ObservableField();
私有最终int-mProductId;
私有最终LiveData mObservableComments;
public ProductViewModel(@NonNull应用程序、数据存储库、,
最终int产品ID){
超级(应用);
MPProductId=productId;
mObservableComments=repository.loadComments(MPProductId);
mObservableProduct=repository.loadProduct(mProductId);
}
/**
*创建者用于将产品ID注入ViewModel
*
*此创建者将展示如何将依赖项注入ViewModels。它不是
*在这种情况下实际上是必要的,因为产品ID可以在公共方法中传递。
*/
公共静态类工厂扩展了ViewModelProvider.NewInstanceFactory{
@非空
私有最终应用程序映射应用程序;
私有最终int-mProductId;
私有最终数据存储库;
公共工厂(@NonNull应用程序,int-productId){
应用=应用;
MPProductId=productId;
mRepository=((basicap)应用程序).getRepository();
}
@凌驾
公共T创建(类modelClass){
//未检查
返回(T)新产品视图模型(MapApplication、mRepository、MPProductId);
}
}
}
产品ID从哪里来
- 如果它是从存储库(数据库或web服务)加载的,我想您不必在ViewModel上公开它
- 如果它是一个“动态”值,存储在SharedReferences中或从视图设置,则可以按如下方式公开设置器
关于样本,当评论说: 可以在公共方法中传递产品ID 这是指您可以创建公共setter方法的事实 由于
productId
用于从数据库获取LiveData,因此您应该使用switchMap
,如您所述。这是因为switchMap
允许您查找和更新LiveData
所指向的内容,而无需重新设置观察者。如果您没有使用开关映射
,则需要告诉您的活动观察新查找的LiveData
,并可能停止观察旧的LiveData
对象
还有一个注意事项-工厂在这里也很有用,因为您正在通过构造函数传入或注入DataRepository
依赖项。这是将存储库放入类中的更好方法,因为在测试时很容易模拟存储库
考虑到这一点,如果您希望在工厂中执行此操作,那么您的代码可能如下所示:
public class ProductViewModel extends AndroidViewModel {
private final LiveData<ProductEntity> mProduct;
private final LiveData<List<CommentEntity>> mComments;
private final MutableLiveData<Integer> mProductId = new MutableLiveData<>();
public ProductViewModel(@NonNull Application application) {
super(application);
// Have some way to get your repository, this is not great for testing...
Repository repository = ((BasicApp) application).getRepository();
mProduct = Transformations.switchMap(mProductId, id -> {
return repository.loadProduct(id);
}
mComments = Transformations.switchMap(mComments, id -> {
return repository.loadComments(id);
}
}
public void setProductId(int productId) {
mProductId.setValue(productId); // This will trigger both of those switchMap statements
}
}
公共类ProductViewModel扩展了AndroidViewModel{
私有最终LiveData MPProduct;
私有最终LiveData mComments;
private final MutableLiveData MPProductId=新的MutableLiveData();
public ProductViewModel(@NonNull应用程序){
超级(应用);
//有一些方法来获取您的存储库,这对于测试来说不是很好。。。
Repository Repository=((BASICAP)应用程序).getRepository();
MPProduct=Transformations.switchMap(MPProductID,id->{
返回repository.loadProduct(id);
}
mComments=Transformations.switchMap(mComments,id->{
返回repository.loadComments(id);
}
}
public void setProductId(int productId){
setValue(productId);//这将触发这两个switchMap语句
}
}
以防有人混淆。它应该是mComments=Transformations.switchMap(MPProductId,…
public void setProductId(int productId) {
if(mProductId == -1) { // or check mObservableComments
mProductId = productId;
mObservableComments = repository.loadComments(mProductId);
mObservableProduct = repository.loadProduct(mProductId);
}
}
public class ProductViewModel extends AndroidViewModel {
private final LiveData<ProductEntity> mProduct;
private final LiveData<List<CommentEntity>> mComments;
private final MutableLiveData<Integer> mProductId = new MutableLiveData<>();
public ProductViewModel(@NonNull Application application) {
super(application);
// Have some way to get your repository, this is not great for testing...
Repository repository = ((BasicApp) application).getRepository();
mProduct = Transformations.switchMap(mProductId, id -> {
return repository.loadProduct(id);
}
mComments = Transformations.switchMap(mComments, id -> {
return repository.loadComments(id);
}
}
public void setProductId(int productId) {
mProductId.setValue(productId); // This will trigger both of those switchMap statements
}
}