Tengo un fragmento que muestra una ventana emergente cuando el usuario se registra con éxito. Si Navegación a un nuevo fragmento y regreso, la ventana emergente con el nombre de usuario anterior se muestra de nuevo. Me fijo este problema utilizando SingleLiveEvent, pero ahora tengo a mi refactorizar código para utilizar MediatorLiveData como mis datos pueden provenir de fuentes (2 remotos y bases de datos), y no es compatible con SingleLiveEvent.
He intentado utilizar una envoltura evento y la eliminación de los observadores en onDestroyView (), pero hasta ahora nada está funcionando, el LiveData onChanged función sigue recibiendo llamadas cuando muevo hacia atrás al fragmento. Aquí es un poco de mi fragmento:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentDashboardBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(getActivity());
//Get the attendanceViewModel for registering attendance
attendanceViewModel = ViewModelProviders.of(this).get(AttendanceViewModel.class);
attendanceViewModel.getAttendance().observe(getViewLifecycleOwner(), attendanceAndMember -> {
if (attendanceAndMember != null && attendanceAndMember instanceof AttendanceMemberModel) {
clokedInOutMember = attendanceAndMember.member;
}
showResultClockInOutPopup();
});
return binding.getRoot();
}
private void showResultClockInOutPopup() {
clockInBuilder = new AlertDialog.Builder(getActivity());
View view = getLayoutInflater().inflate(R.layout.status_clock_in_out_popup, null);
TextView responseClockInOut = view.findViewById(R.id.responseClockInOut);
Button dismissButton = view.findViewById(R.id.dismissButton);
//Setup Popup Text
if (clokedInOutMember != null) {
if (StringToBool(clokedInOutMember.is_clocked_in_temp)) {
responseClockInOut.setText("Bienvenue " + clokedInOutMember.name + ", tu es bien enregistré(e).");
} else {
responseClockInOut.setText("Désolé de te voir partir " + clokedInOutMember.name + ", à bientôt!");
}
} else {
responseClockInOut.setText("Oups, il semblerait qu'il y ait une erreur...\n Essaye à nouveau.");
}
[..SETUP ALERTDIALOG...]
//Dismiss popup
dismissButton.setOnClickListener(v -> {
clockInResultDialog.dismiss();
clockInResultPopupShowed = false;
clokedInOutMember = null;
});
clockInResultDialog.show();
clockInResultPopupShowed = true;
}
}
@Override
public void onDestroyView() {
attendanceViewModel.getAttendance().removeObservers(this);
super.onDestroyView();
}
Y aquí es mi modelo de vista, tengo que usar transformaciones como que estoy recibiendo el ID de usuario a partir del fragmento, pasando al modelo de vista, que lo pasa al depósito de consulta (tal vez hay una manera mejor?):
public class AttendanceViewModel extends AndroidViewModel {
private AttendanceRepository repository = AttendanceRepository.getInstance();
public LiveData<AttendanceMemberModel> mAttendanceAndMember;
private MutableLiveData<String> mId = new MutableLiveData<>();
private MediatorLiveData<AttendanceMemberModel> mObservableAttendance = new MediatorLiveData<AttendanceMemberModel>();
{
mObservableAttendance.setValue(null);
mAttendanceAndMember = Transformations.switchMap(mId, id -> {
return repository.saveAttendance(id);
});
mObservableAttendance.addSource(mAttendanceAndMember, mObservableAttendance::setValue);
}
public AttendanceViewModel(@NonNull Application application) {
super(application);
}
public LiveData<AttendanceMemberModel> getAttendance() {
return mObservableAttendance;
}
public void setMemberId(String id) {
mId.setValue(id);
}
@Override
protected void onCleared() {
mObservableAttendance.setValue(null);
super.onCleared();
}
}
Te puedo sugerir dos maneras. En primer lugar crear una boolean
variable de si el diálogo se muestra en Fragment
y después de mostrar conjunto de diálogo que true
y antes de mostrar verificación de diálogo si se demuestra diálogo. La segunda manera es después de mostrar conjunto de diálogo livedata
valor de nulo y de verificación si el valor nulo de observador antes de mostrar de diálogo. Yo prefiero segunda manera.