java - 使用 ViewModel 仅在用户干预时调用
问题描述
在我的片段中,检查用户以查看他们的电子邮件是否在数据库中并转到注册或登录流程,我使用 ViewModel,此视图模型使用电子邮件作为 MutableLiveData,这工作正常,但是当用户返回时,它会记住电子邮件已经保存,然后立即与 API 对话,再次将它们向前推。
等待用户调用的方法是什么?到目前为止,对于其他所有内容,使用菜单,它会在没有用户干预的情况下获取数据并在更改时更改显示给用户的数据是正确的。然而这是不同的。
我的(当然很差)视图模型是:
public class ExistingUserViewModel extends ViewModel {
private final MutableLiveData<String> email = new MutableLiveData<>();
private final LiveData<ApiResponse<ExistingUserResponse>> existingUser;
@Inject
public ExistingUserViewModel(@NonNull ExistingUserRepository existingUserRepository){
existingUser = Transformations.switchMap(email, input -> {
if (input == null){
return AbsentLiveData.create();
}
return existingUserRepository.isExistingUser(input);
});
}
public LiveData<ApiResponse<ExistingUserResponse>> getIsExistingUser() { return existingUser; }
@VisibleForTesting
public void setEmail(String email1){
email.setValue(email1);
}
}
我的片段:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((MainActivity) getActivity()).getSupportActionBar().hide();
existingUserViewModel = ViewModelProviders.of(this, viewModelFactory).get(ExistingUserViewModel.class);
existingUserListener();
}
private void refreshAndObserve() {
existingUserViewModel.getIsExistingUser().observe(this, result -> {
if (result.isSuccessful()) {
try {
String email = binding.get().emailEditText.getText().toString();
if (result.body.getExists()) { // user exists
navigationController.navigateToLogin(email,null);
} else {
navigationController.navigateToRegisterName(email);
}
} catch (NullPointerException e){
Toast.makeText(getActivity(),e.toString(),Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getActivity(),result.errorMessage,Toast.LENGTH_SHORT).show();
}
});
}
private void existingUserListener(){
binding.get().continueButton.setOnClickListener(v -> submitDetails(v));
binding.get().emailEditText.setOnKeyListener((v, keyCode, event) -> {
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
submitDetails(v);
return true;
}
return false;
});
}
private void submitDetails(View v) {
refreshAndObserve();
String email = binding.get().emailEditText.getText().toString();
dismissKeyboard(v.getWindowToken());
//todo: if valid do below
existingUserViewModel.setEmail(email);
}
我玩过什么时候进行观察,但不确定如何最好地处理这个数据保留问题
解决方案
我现在能想到的唯一方法是将一个布尔值应用于 submitDetails 到 isUserClicked 并将其设置为 false 在 onCreateView 中并再次将其设置为 true submitDetails 然后将观察者更改为 && isUserClicked。对此作为解决方案不满意,但它至少会起作用。
还注意到我必须删除一个观察者,因为它正在堆叠到我的 popstack 上,所以解决了,如果其他人有兴趣
try {
String email = binding.get().emailEditText.getText().toString();
existingUserViewModel.getIsExistingUser().removeObservers(this);
if (result.body.getExists()) { // user exists
navigationController.navigateToLogin(email, null);
} else {
navigationController.navigateToRegisterName(email);
}
} catch (NullPointerException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_SHORT).show();
}
推荐阅读
- python - 退出后如何重新启动 Selenium 浏览器?
- java - Spring Controller 不被视为单例
- flutter - Flutter ListView/ListTiles 未在页面上呈现
- android - 在 Kotlin 中编辑之前清除文本
- excel - 如何创建一个询问您是否要重命名工作表的宏?
- apache - 如何授权属于包含哈希的组的用户
- flutter - Flutter:如何将内部按钮与外部按钮的左侧对齐
- c# - Web API .NET MVC - Http POST - Fiddler 请求发送字符串变量
- jenkins - 第一个错误后如何在所有节点上停止詹金斯构建
- google-cloud-platform - 在 Google Cloud 中使用 Stackdriver 检查应用程序状态