Java 中的 Android 架构 SingleLiveEvent 和 EventObserver 实践示例 [英] Android Architecture SingleLiveEvent and EventObserver Practicle Example in Java
问题描述
我尝试使用两个字段(用户名,密码
)制作示例登录页面,并使用android架构组件保存按钮,使用android数据绑定,验证viewmodel
中的数据并且从视图模型我调用存储库以进行远程服务器调用,如官方文档中所述,远程服务器成功返回我的用户 ID,那么如何使用此成功从视图模型启动新片段?我了解了一些关于 singleLiveEvent
和 EventObserver
的知识,但我找不到明确的用法示例:
I try to make sample login page with two fields (username, password
) and save button with android architecture component, using android data binding, validating the data in viewmodel
and from view model I make call to repository for remote server call as mentioned in official doc, remote server return me userid with success so how can I start new fragment from view model using this success? I learn something about singleLiveEvent
and EventObserver
, but I'm not able to find there clear usage example:
登录视图模型
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
?有什么实际例子吗?
How can I use EventObserver
in above case? Any practical example?
推荐答案
查看以下示例,了解如何创建 单个 LiveEvent 以仅观察一次 LiveData
:
Check out below example about how you can create single LiveEvent to observe only one time as LiveData
:
创建一个名为 Event
的类,如下所示,它将提供我们的数据一次并充当 LiveData
包装器的子级:
Create a class called Event
as below that will provide our data once and acts as child of 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
:
Then declare this EventObserver
class like below so that we don't end up placing condition for checking about Event
handled every time, everywhere :
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(""));
参考 在这里了解详情.
Refer here for details.
编辑O.P.:
是的,data.setValue(new Event(""));
用于当您从 API 得到响应(记得返回与您在 VM 中采用的相同 LiveData
类型,而不是 SingleLiveEvent
类).
Yes, data.setValue(new Event(""));
is meant for repository when you've got response from API (Remember to return same LiveData
type you've taken in VM instead of SingleLiveEvent
class though).
所以,假设您已经在 ViewModel
中创建了 LiveData
,如下所示:
So, let's say you've created LiveData
in ViewModel
like below :
private MutableLiveData<Event<String>> snackbarStringSingleLiveEvent= new MutableLiveData<>();
您将此实时数据作为单个事件从如下存储库中提供价值:
You provide value to this livedata as Single Event from repository like below :
@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 (Fragment) 上观察它,如下所示:
And observe it on UI (Fragment) like below :
viewModel.getSnackbarStringSingleLiveEvent().observe(this, new EventObserver<String>(data -> {
// your unhandled data would be here for one time.
}));
这篇关于Java 中的 Android 架构 SingleLiveEvent 和 EventObserver 实践示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!