java - Java 中的 Android 架构 SingleLiveEvent 和 EventObserver 实践示例
问题描述
我尝试使用两个字段(username, password
)制作示例登录页面并使用 android 架构组件保存按钮,使用 android 数据绑定,验证视图模型中viewmodel
和视图模型中的数据我调用存储库以进行远程服务器调用,如官方文档中所述,远程服务器成功返回我的用户 ID 那么如何使用此成功从视图模型开始新片段?我学到了一些关于singleLiveEvent
and的知识EventObserver
,但我找不到明确的用法示例:
登录视图模型
private MutableLiveData<String> snackbarStringSingleLiveEvent= new MutableLiveData<>();
@Inject
public LoginViewModel(@NonNull AppDatabase appDatabase,
@NonNull JobPortalApplication application,
@NonNull MyApiEndpointInterface myApiEndpointInterface) {
super(application);
loginRepository = new LoginRepository(application, appDatabase, myApiEndpointInterface);
snackbarStringSingleLiveEvent = loginRepository.getLogin(username.get(), password.get(), type.get());
}
public MutableLiveData<String> getSnackbarStringSingleLiveEvent() {
return snackbarStringSingleLiveEvent;
}
存储库
public SingleLiveEvent<String> getLogin(String name, String password, String type) {
SingleLiveEvent<String> mutableLiveData = new SingleLiveEvent<>();
apiEndpointInterface.getlogin(name, password, type).enqueue(new Callback<GenericResponse>() {
@Override
public void onResponse(Call<GenericResponse> call, Response<GenericResponse> response) {
mutableLiveData.setValue(response.body().getMessage());
}
@Override
public void onFailure(Call<GenericResponse> responseCall, Throwable t) {
mutableLiveData.setValue(Constant.FAILED);
}
});
return mutableLiveData;
}
登录片段
private void observeViewModel(final LoginViewModel viewModel) {
// Observe project data
viewModel.getSnackbarStringSingleLiveEvent().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
}
});
}
EventObserver
在上述情况下如何使用?有什么实际的例子吗?
解决方案
查看以下示例,了解如何创建单个 LiveEvent以仅观察一次LiveData
:
创建一个Event
如下所示的类,它将提供我们的数据一次并充当LiveData
wrapper 的子级:
public class Event<T> {
private boolean hasBeenHandled = false;
private T content;
public Event(T content) {
this.content = content;
}
public T getContentIfNotHandled() {
if (hasBeenHandled) {
return null;
} else {
hasBeenHandled = true;
return content;
}
}
public boolean isHandled() {
return hasBeenHandled;
}
}
然后EventObserver
像下面这样声明这个类,这样我们就不会每次都放置检查处理的条件,到处都是:Event
public class EventObserver<T> implements Observer<Event<T>> {
private OnEventChanged onEventChanged;
public EventObserver(OnEventChanged onEventChanged) {
this.onEventChanged = onEventChanged;
}
@Override
public void onChanged(@Nullable Event<T> tEvent) {
if (tEvent != null && tEvent.getContentIfNotHandled() != null && onEventChanged != null)
onEventChanged.onUnhandledContent(tEvent.getContentIfNotHandled());
}
interface OnEventChanged<T> {
void onUnhandledContent(T data);
}
}
以及如何实现它:
MutableLiveData<Event<String>> data = new MutableLiveData<>();
// And observe like below
data.observe(lifecycleOwner, new EventObserver<String>(data -> {
// your unhandled data would be here for one time.
}));
// And this is how you add data as event to LiveData
data.setValue(new Event(""));
详情请参阅此处。
编辑OP:
是的,data.setValue(new Event(""));
当您从 API 获得响应时,它适用于存储库 (请记住返回LiveData
您在 VM 中使用的相同类型而不是SingleLiveEvent
类)。
LiveData
因此,假设您已创建ViewModel
如下:
private MutableLiveData<Event<String>> snackbarStringSingleLiveEvent= new MutableLiveData<>();
您为这个 livedata 提供价值作为来自存储库的单个事件,如下所示:
@Override
public void onResponse(Call<GenericResponse> call, Response<GenericResponse> response) {
mutableLiveData.setValue(new Event(response.body().getMessage())); // we set it as Event wrapper class.
}
并在 UI (片段)上观察它,如下所示:
viewModel.getSnackbarStringSingleLiveEvent().observe(this, new EventObserver<String>(data -> {
// your unhandled data would be here for one time.
}));
推荐阅读
- javascript - 如何访问此网格的行对象?
- python - 如何检查 url 是否不在 i18n_pattern 中?
- mysql - Laravel whereBetween 不起作用。表明?
- android - 从后台带回片段时的Android片段生命周期
- ios - 在 Xcode 中禁用记录 UI 测试
- groovy - Groovy withBatch 无需关闭
- python - 如何在 matplotlib 中使用时间序列绘制单个行值
- java - 层次关系的图遍历
- machine-learning - 关于 XGBoost 的问题
- batch-file - 将文件从一台服务器复制到另一台服务器出现 NTFS 错误