android - 在 android mvvm 中处理导航

标签 android mvvm viewmodel android-livedata

我正在构建一个 android 应用程序,但我不确定如何在 MVVM 架构中实现导航。
我采取的第一种方法是将点击事件按钮绑定(bind)到 ViewModel 中的一个函数,该函数在必要时执行一些逻辑(例如一些数据验证),然后触发一个 LiveData 事件(告诉 View 导航到不同的屏幕)到观察 ViewModel 的 View 。

<button android:id="@+id/btnId"
        android:onClick="@{(v) -> myViewModel.onSaveClick()}"
        .../>

class MyViewModel : ViewModel() {
    val saveNavigation = MutableLiveData<Event<Customer>>()
    val errorMessage = MutableLiveData<Event<String>>()

    fun onSaveClick() {
        if (validateCustomer(customer)) {
            repository.save(customer)
            saveNavigation.value = Event(customer)
        }
        else
            errorMessage.value = Event("error")
    }
}

class View : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        //observe event protects from re-reading the value on screen rotation
        myViewModel.saveNavigation.observeEvent(this) {
             findNavController().navigate(CustomerViewDirections
                    .actionCustomerInfoToCustomerBalanceHistory(it))
        }

        myViewModel.errorMessage.observeEvent(this) { toast(it) }
    }
}


第二种方法是 View 注册到 onClickListener 并主动调用 ViewModel 逻辑函数(例如验证),然后 View 才进行导航

class MyViewModel : ViewModel() {

    fun save() : Status {
        if (validateCustomer(customer)) {
            repository.save(customer)
            return Status.OK
        }
        else
            return Status.Error //or some string message
    }
}

class View : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        btnId.setOnClickListener {
            if (myViewModel.save() == Status.OK) 
                findNavController().navigate(CustomerViewDirections
                    .actionCustomerInfoToCustomerBalanceHistory(myViewModel.customer))
            else
                toast("error")
        }
    }
}


这两种方式中哪一种更适合 MVVM 架构,或者可能还有其他选择?

最佳答案

我建议您创建一个 Navigator 界面,使用您选择的依赖注入(inject)将其注入(inject)您的 ViewModel。然后,您在处理导航的组件中实现该接口(interface)。然后,您将使用该 Navigator 界面中的方法进行导航。

例如,

interface Navigator {
    fun navigateToSettings()
}

class NavigatorImpl : Navigator {
    override fun navigateToSettings() {
        TODO()
    }
}

关于android - 在 android mvvm 中处理导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57236005/

相关文章:

java - 为什么我们要从存储库返回实时数据? (MVVM 安卓)

c# - 无法理解 ViewModel 和模型之间的区别

c# - Entity 到 ViewModel 的映射真的需要 AutoMapper/ValueInjector 吗?

java.security.InvalidKeyException : Wrong key size

javascript - 在 Chrome PWA 中更改屏幕方向

c# - WPF 样式的 DataTrigger 绑定(bind)

xamarin - 1 属性未更新 Xamarin 表单绑定(bind)

wpf - WPF在 View 中更改ViewModel属性

java - 在数据库的第一个中添加新项目(位置 0)

java - Android相机 Intent 保存文件两次/如何避免