バックフラグメントに移動するとき、それが二回表示されませんのでlivedataからオブザーバを削除する方法

ベラ:

私はこれを表示し、ユーザーが正常にログインされたポップアップの断片を持っている。私は新しいフラグメントにナビゲートして戻ってきた場合は、以前のユーザー名とポップアップが再び示されています。私はSingleLiveEventを使用してこの問題を修正したが、私は今、私のデータが2つのソース(リモートおよびデータベース)から来ることができるようMediatorLiveDataを使用するように私のコードをリファクタリングする必要があり、それはSingleLiveEventと互換性がありません。

livedata onChangedイベント機能は、私は戻ってフラグメントに移動したときに呼び出されるばかり続けて、私は(イベントラッパーを使用してonDestroyViewにオブザーバーを削除しようとした)が、これまでのところ、何も作業していません。ここに私のフラグメントの一部です:

@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();
}

そしてここで、私は、クエリのリポジトリに渡しViewModelにに渡し、私はフラグメントからのuserIdを取得していますような変換を使用する必要が私のViewModelにある(多分もっと良い方法があります?):

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();
}
}
ディフェンダー:

私はあなたに二つの方法を提案することができます。最初の作成booleanダイアログがで示されているかどうかを変数Fragmentとそれにダイアログセットを表示した後true、ダイアログが表示されている場合は、ダイアログのチェックを表示する前に。第二の方法は、ダイアログセット表示した後でlivedata、ダイアログを表示する前に観測値はnullの場合はnullチェックに値を。私は、第二の方法を好みます。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=277305&siteId=1