Java 中的 Android 架构 SingleLiveEvent 和 EventObserver 实践示例 [英] Android Architecture SingleLiveEvent and EventObserver Practicle Example in Java

查看:15
本文介绍了Java 中的 Android 架构 SingleLiveEvent 和 EventObserver 实践示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用两个字段(用户名,密码)制作示例登录页面,并使用android架构组件保存按钮,使用android数据绑定,验证viewmodel中的数据并且从视图模型我调用存储库以进行远程服务器调用,如官方文档中所述,远程服务器成功返回我的用户 ID,那么如何使用此成功从视图模型启动新片段?我了解了一些关于 singleLiveEventEventObserver 的知识,但我找不到明确的用法示例:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆