使用ViewModel仅在用户干预下调用

问题描述 投票:0回答:1

在我检查用户是否查看其电子邮件是否在数据库中并进入注册流程或登录流程的片段中,我使用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);
}

我玩过什么时候进行观察,但不确定如何最好地解决此数据保留问题

java android mvvm observer-pattern
1个回答
0
投票

我现在唯一想到的方法是将一个布尔值应用到SubmitDetails的isUserClicked上,并将其作为false放在onCreateView中,然后将它再次设为true,然后在SubmitDetails中将它更改为&& isUserClicked。对于此解决方案不满意,但至少可以使用。

还注意到我必须删除一个观察者,因为它正堆积在我的弹出堆栈上,所以解决了,如果有人感兴趣的话

            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();
            }
© www.soinside.com 2019 - 2024. All rights reserved.