1

所以,我刚刚开始尝试LiveData- 我正忙于一个新项目,我正在使用的地方ViewModel以及LiveData-RESTFul我用来获取数据的一些服务,它们不带参数并返回一些数据。

MVVM 范例的典型设置LiveData如下所示:

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

现在,当我们离开这个活动,去一个新的活动,通过使用意图或其他方式,而不是按下后退按钮(所以,finalize没有被调用) - 然后回到MyActivity- 我们当然不获取users再次,因为我们仍然应该拥有该数据。

但是,如果我们确实想再次获取它们怎么办?

从我所看到的来看,正确执行此操作的唯一方法似乎是在getUsers() LiveData对象上调用“setValue”

像这样的东西:

public class MyActivity extends AppCompatActivity {
    public void onResume() {
     viewModel.setActive(true); 
    }
}

ViewModel看起来像这样:

  private final MutableLiveData<Boolean> activeLiveData = new MutableLiveData<>();

 ViewModel(ViewModelRepo repo){
      this.repo = repo;

      results = Transformations.switchMap(activeLiveData, active ->{
        if(active){
          return repo.getUsers();
        }else {
          return AbsentLiveData.create(); //"Null live data"
        }
      });
  }

   LiveData<Users>> getUsers() {
    return results;
  }

 //This could be called "update" with no params 
  void setActive(boolean active) {
    activeLiveData.setValue(active);
  }

我决定这样做的一个原因是因为谷歌不希望我们这样做:

class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    public MyViewModel(PostalCodeRepository repository) {
       this.repository = repository;
    }

    private LiveData<String> getPostalCode(String address) {
       // DON'T DO THIS
       return repository.getPostCode(address);
    }
}

为此原因:

如果这是实现,则 UI 需要在每次调用 getPostalCode() 时从以前的 LiveData 中注销并重新注册到新实例。此外,如果重新创建 UI,它会触发对 repository.getPostCode() 的另一个调用,而不是使用先前调用的结果。

有没有更好的方法来ViewModel“重做”它的repo.getUsers()调用?也许我可以创建一个方法,说“Update()”而不是“活动”,但仍然 - 它以不同的方式做同样的事情。

4

1 回答 1

3

好吧,您正在 ViewModel 的创建者中进行获取,它将事物锁定到位。通常他们会建议在 getter 中获取数据,如果数据不存在的话。

所以一个不错的选择是首先使用常规模式:

  private MutableLiveData<Users> users = null;

 ViewModel(ViewModelRepo repo){
      this.repo = repo;
  }

   LiveData<Users> getUsers() {
    if (users = null) {
      fetchUsers();
    }
    return users;
  }

  public void fetchUsers() {
    users.postValue(repo.getUsers());
  }

然后从您的活动/片段中,每当您觉得有必要“刷新用户”时,您只需调用viewModel.fetchUsers();

于 2017-10-11T09:44:59.483 回答