Android:MVVM是否可以显示来自ViewModel的消息(toast/snackbar等)

我想知道在ViewModel的视图中显示某种消息的最佳方法是什么。我的视图模型正在进行POST调用和“onResult”我想弹出一条消息给用户,其中包含某个消息。

这是我的视图模型:

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);       
}

在这种情况下,最好的方法是什么?


答案 1

我们可以使用类作为解决方案。但它只会发送一次更新。根据我个人的经验,使用事件包装类是最好的解决方案。SingleLiveEventLiveDataMutableLiveData

下面是一个简单的代码示例。

步骤1:创建一个类(这是一个样板代码,您可以将其重用于任何Android项目)。Event

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 类的顶部,定义一个 with 包装器(我在这里使用了一个 String,但你可以使用所需的数据类型)和相应的实时数据进行封装。MutableLiveData

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()
     }
 })

答案 2

使用 LiveData 从视图模型在视图中显示 Toast/小吃条消息(活动/片段)。

步:

  • 将实时数据添加到视图模型中
  • 查看只是观察实时数据并更新视图相关任务

例如:

在视图模型中:

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
    }
})

推荐