Ver*_*era 7 java android android-livedata mediatorlivedata
我有一个片段,当用户成功登录时会显示一个弹出窗口。如果我导航到一个新片段并返回,则会再次显示带有先前用户名的弹出窗口。我使用 SingleLiveEvent 修复了这个问题,但现在必须重构我的代码以使用 MediatorLiveData,因为我的数据可以来自 2 个源(远程和数据库),并且它与 SingleLiveEvent 不兼容。
\n\n我尝试使用事件包装器并删除 onDestroyView() 上的观察者,但到目前为止没有任何效果,当我移回片段时,livedata onChanged 函数不断被调用。这是我的一些片段:
\n\n@Override\npublic View onCreateView(LayoutInflater inflater, ViewGroup container,\n Bundle savedInstanceState) {\n // Inflate the layout for this fragment\n binding = FragmentDashboardBinding.inflate(inflater, container, false);\n binding.setLifecycleOwner(getActivity());\n\n //Get the attendanceViewModel for registering attendance\n attendanceViewModel = ViewModelProviders.of(this).get(AttendanceViewModel.class);\n attendanceViewModel.getAttendance().observe(getViewLifecycleOwner(), attendanceAndMember -> {\n if (attendanceAndMember != null && attendanceAndMember instanceof AttendanceMemberModel) {\n clokedInOutMember = attendanceAndMember.member;\n }\n showResultClockInOutPopup();\n });\n\n return binding.getRoot();\n}\n\nprivate void showResultClockInOutPopup() {\n\n clockInBuilder = new AlertDialog.Builder(getActivity());\n\n View view = getLayoutInflater().inflate(R.layout.status_clock_in_out_popup, null);\n TextView responseClockInOut = view.findViewById(R.id.responseClockInOut);\n Button dismissButton = view.findViewById(R.id.dismissButton);\n\n //Setup Popup Text\n if (clokedInOutMember != null) {\n if (StringToBool(clokedInOutMember.is_clocked_in_temp)) {\n responseClockInOut.setText("Bienvenue " + clokedInOutMember.name + ", tu es bien enregistr\xc3\xa9(e).");\n } else {\n responseClockInOut.setText("D\xc3\xa9sol\xc3\xa9 de te voir partir " + clokedInOutMember.name + ", \xc3\xa0 bient\xc3\xb4t!");\n }\n } else {\n responseClockInOut.setText("Oups, il semblerait qu\'il y ait une erreur...\\n Essaye \xc3\xa0 nouveau.");\n }\n\n [..SETUP ALERTDIALOG...]\n\n //Dismiss popup\n dismissButton.setOnClickListener(v -> {\n clockInResultDialog.dismiss();\n clockInResultPopupShowed = false;\n clokedInOutMember = null;\n });\n\n clockInResultDialog.show();\n clockInResultPopupShowed = true;\n }\n\n}\n\n@Override\npublic void onDestroyView() {\n attendanceViewModel.getAttendance().removeObservers(this);\n super.onDestroyView();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是我的 ViewModel,我必须使用转换,因为我从片段中获取 userId,传递给 Viewmodel,Viewmodel 将其传递到存储库进行查询(也许有更好的方法?):
\n\npublic class AttendanceViewModel extends AndroidViewModel {\n\nprivate AttendanceRepository repository = AttendanceRepository.getInstance();\npublic LiveData<AttendanceMemberModel> mAttendanceAndMember;\nprivate MutableLiveData<String> mId = new MutableLiveData<>();\n\nprivate MediatorLiveData<AttendanceMemberModel> mObservableAttendance = new MediatorLiveData<AttendanceMemberModel>();\n{\n mObservableAttendance.setValue(null);\n\n mAttendanceAndMember = Transformations.switchMap(mId, id -> {\n return repository.saveAttendance(id);\n });\n\n mObservableAttendance.addSource(mAttendanceAndMember, mObservableAttendance::setValue);\n}\n\n\npublic AttendanceViewModel(@NonNull Application application) {\n super(application);\n}\n\npublic LiveData<AttendanceMemberModel> getAttendance() {\n return mObservableAttendance;\n\n}\n\npublic void setMemberId(String id) {\n mId.setValue(id);\n}\n\n\n@Override\nprotected void onCleared() {\n mObservableAttendance.setValue(null);\n super.onCleared();\n}\n}\nRun Code Online (Sandbox Code Playgroud)\n
我可以建议你两种方法。首先创建一个boolean变量是否显示对话框,Fragment并在显示对话框之后将其设置为true,并在显示对话框之前检查是否显示对话框。第二种方法是在显示对话框之后将livedata值设置为 null 并在显示对话框之前检查观察者值是否为 null。我更喜欢第二种方式。
| 归档时间: |
|
| 查看次数: |
8167 次 |
| 最近记录: |