ViewModelからのビューにある種のメッセージを表示するための最良のアプローチは何か知りたいです。私のViewModelはPOST呼び出しと "onResult"を実行しています。特定のメッセージを含むメッセージをユーザーにポップアップしたいと思います。
これは私のViewModelです:
public class RegisterViewModel extends ViewModel implements Observable {
.
.
.
public void registerUser(PostUserRegDao postUserRegDao) {
repository.executeRegistration(postUserRegDao).enqueue(new Callback<RegistratedUserDTO>() {
@Override
public void onResponse(Call<RegistratedUserDTO> call, Response<RegistratedUserDTO> response) {
RegistratedUserDTO registratedUserDTO = response.body();
/// here I want to set the message and send it to the Activity
if (registratedUserDTO.getRegisterUserResultDTO().getError() != null) {
}
}
});
}
そして私の活動:
public class RegisterActivity extends BaseActivity {
@Override
protected int layoutRes() {
return R.layout.activity_register;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
ActivityRegisterBinding binding = DataBindingUtil.setContentView(this, layoutRes());
binding.setViewModel(mRegisterViewModel);
}
この場合の最善のアプローチは何でしょうか?
LiveDataを使用して、viewmodelからビューにメッセージの種類を表示します。
ステップ:
例えば:
Viewmodelの場合:
var status = MutableLiveData<Boolean?>()
//In your network successfull response
status.value = true
アクティビティまたはフラグメント内:
yourViewModelObject.status.observe(this, Observer { status ->
status?.let {
//Reset status value at first to prevent multitriggering
//and to be available to trigger action again
yourViewModelObject.status.value = null
//Display Toast or snackbar
}
})
SingleLiveEventクラスをソリューションとして使用できます。ただし、更新を1回だけ送信するのはLiveDataです。私の個人的な経験では、MutableLiveDataでイベントラッパークラスを使用するのが最善の解決策です。
これは簡単なコードサンプルです。
ステップ1:イベントクラスを作成します(これは、任意のAndroidプロジェクト)で再利用できる定型コードです)
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
ステップ2:ビューモデルクラスの上部で、ラッパーを使用してMutableLiveDataを定義し(ここでは文字列を使用しました。必要なデータ型を使用できます)、カプセル化に対応するライブデータを定義します。
private val statusMessage = MutableLiveData<Event<String>>()
val message : LiveData<Event<String>>
get() = statusMessage
ステップ3:このようにViewModelの機能を使用してステータスメッセージを更新できます。
statusMessage.value = Event("User Updated Successfully")
ステップ4:
ビュー(アクティビティまたはフラグメント)からライブデータを監視するコードを記述します
yourViewModel.message.observe(this, Observer {
it.getContentIfNotHandled()?.let {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
}
})