Я хочу знать, как лучше всего отображать какое-либо сообщение в представлении из 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:
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
}
})
просто примечание для тех, кто не знаком с синтаксисом Kotlin, что оператор безопасного вызова?. будет работать независимо от того, имеет ли статус true или false. док
Не идеальный шаблон - LiveData выводит последнее значение после возобновления просмотра (активности / фрагмента) из фона, что означает, что тост или панель закусок будут показаны снова. Я сам ищу хороший дизайн с помощью SingleLiveEvent.
В качестве решения мы можем использовать класс SingleLiveEvent. Но это LiveData, который отправляет обновление только один раз. По моему личному опыту, использование класса Event Wrapper с MutableLiveData - лучшее решение.
Вот простой пример кода.
Шаг 1 :
Создайте класс Event (это шаблонный код, который можно повторно использовать для любого проекта 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 :
В верхней части класса View Model определите MutableLiveData с оболочкой (здесь я использовал String, но вы можете использовать требуемый тип данных) и соответствующие живые данные для инкапсуляции.
private val statusMessage = MutableLiveData<Event<String>>()
val message : LiveData<Event<String>>
get() = statusMessage
Шаг 3 :
Вы можете обновить статусное сообщение в функциях ViewModel следующим образом:
statusMessage.value = Event("User Updated Successfully")
Шаг 4:
Напишите код для наблюдения за живыми данными с View (активность или фрагмент)
yourViewModel.message.observe(this, Observer {
it.getContentIfNotHandled()?.let {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
}
})
Блестящее решение. При этом учитывается поворот экрана и другие изменения жизненного цикла.
Для этого можно использовать обычный интерфейс обратного вызова.