Tengo un formulario de registro y quiero mostrar un mensaje al usuario basado en el hasta con éxito o no. Almaceno ese mensaje en mi modelo de vista que tiene un objeto de datos en vivo mutable para almacenar ese mensaje y observar ese objeto de mi actividad. Mi problema es cuando hago clic en el botón de registro la primera vez que funciona normalmente, mostrando Toast con mi mensaje como se esperaba, pero cuando hago clic en ese botón nuevamente, el mensaje Toast muestra mi mensaje dos veces. Realmente no entendí qué está mal con mi código. Aquí está mi código.

RegisterActivity

  mViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(RegisterActivityViewModel.class);
  mRegisterBtn.setOnClickListener(v -> {
        register();
    }); 
   private void register() {
    if (!GenericMethods.checkInputField(mKadi) || !GenericMethods.checkInputField(mEmail)
            || !GenericMethods.checkInputField(mPAss)) {
        Toast.makeText(this, "Alanlar boş geçilemez", Toast.LENGTH_SHORT).show();
        return;
    }
    signup();
}
    private void signup(){
    kAdi = mKadi.getText().toString().trim();
    email = mEmail.getText().toString().trim();
    parola = mPAss.getText().toString().trim();
    parolaTekrari = mValidpass.getText().toString().trim();
    il=mIlTv.getText().toString().trim();
    ilce=mIlceTv.getText().toString().trim();
    getRadioValue(mRadioGroup);
    üniversite=mUniTv.getText().toString().trim();
    User user = new User(kAdi,email,parola,cinsiyet,il,ilce,üniversite);
    mViewModel.signup(user);
    mViewModel.signupData.observe(this,status ->{
       Toast.makeText(RegisterActivity.this, status, Toast.LENGTH_SHORT).show();
   });
}

Registrar ActivityViewModel

public MutableLiveData<String> signupData = new MutableLiveData<>();

private String statusString=null;

public void fetchFromRemote() {
    isLoading.setValue(true);
    disposable.add(RetroService.getInstance().getIller()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableSingleObserver<List<Response>>() {
                @Override
                public void onSuccess(@NonNull List<Response> responses) {
                    isLoading.setValue(false);
                    adresList.setValue(responses);
                }
                @Override
                public void onError(@NonNull Throwable e) {
                    isLoading.setValue(false);
                }
            }));
}

public void signup(User user) {
    Repo.getInstance().signup(user)
            .enqueue(new Callback<Void>() {
                @Override
                public void onResponse(Call<Void> call, retrofit2.Response<Void> response) {

                    if (response.code() == 200) {
                    statusString="Success!";
                    } else if (response.code() == 400) {
                    statusString="email already exists";
                    }
                    signupData.setValue(statusString);
                }
                @Override
                public void onFailure(Call<Void> call, Throwable t) {
                    signupData.setValue(t.getMessage());
                }
            });

}

@Override
protected void onCleared() {
    super.onCleared();
    disposable.clear();
}
1
Jarnojr 23 oct. 2020 a las 18:42

1 respuesta

La mejor respuesta

Porque la función "registrar" crea un nuevo observador cada vez que se llama. Este es el observador:

Observer<String> signupDataObserver = status -> {
    Toast.makeText(RegisterActivity.this, status, Toast.LENGTH_SHORT).show();
}

Cada vez que se hace clic en el botón, la función agrega un nuevo observador en MutableLiveData "signUpData":

mViewModel.signupData.observe(this, signupDataObserver);

Entonces, si mueve la función "observar" al evento "OnCreateView", el problema debería resolverse, porque el fragmento registrará solo 1 observador cuando se cree la vista y no cuando se haga clic en el botón. Otra opción sería eliminar el observador después de que se haya entregado el mensaje de brindis:

Observer<String> signupDataObserver = status -> {
    Toast.makeText(RegisterActivity.this, status, Toast.LENGTH_SHORT).show();
    mViewModel.signupData.removeObserver(signupDataObserver);
}

mViewModel.signupData.observe(this, signupDataObserver);
0
zjmo 23 oct. 2020 a las 16:47