视图模型 + 数据绑定中的最佳做法和模式.ViewModel 中的 ObservableField 可以吗?



浏览示例,我看到了 2 种使用 Android 架构组件的 MVVM 方法。

第一种方法:

  1. ViewModel提供LiveData
  2. Activity订阅LiveData
  3. 当被调用的观察者Activity将数据设置为ViewModelObservableField时。
  4. 整个ViewModel传递到绑定。
  5. xml中,您只需将ObservableField设置为值

    <ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    app:visibleGone="@{viewmodel.listLoading}"/>
    <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swiperefresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:refreshing="@{viewmodel.listRefreshing}"
    app:onRefreshListener="@{() -> viewmodel.refreshList()}"
    app:visibleGone="@{!viewmodel.listLoading}">
    

优点:我不需要传递状态(例如"加载"),因为我在ViewModel中更新listLoadingObservableField如下:

val listLoading = ObservableBoolean(false)
/** other observable fields go here **/
val list: MutableLiveData<List<Item>> = MutableLiveData()
fun loadList() {
listLoading.set(true)
repo.getList { items ->
list.value = items
listLoading.set(false)
}
}

缺点这种方法有什么缺点吗?

第二种方法:

  1. ViewModel提供LiveData
  2. Activity订阅LiveData
  3. 当调用Activity的观察者传递给绑定时
  4. 仅将所需的对象 (pojo) 传递给绑定

优点:这种方法有什么优点吗?

缺点:状态应该从ViewModel返回。在此示例中,来自 Google 的数据包装在Resource对象中。

第一种方法用于谷歌的另一个示例应用

我想知道这两种模式的优缺点是什么,这些开发人员在使用 Android 数据绑定和 Android Arch 组件方面拥有更多经验。

您应该考虑将视图逻辑与业务逻辑拆分。

由于您有一个使用数据绑定和 AAC 来处理的 ViewModel,因此您还应该分离视图(布局)内的逻辑。

只需将两个变量传递给布局即可。一个是 VievModel,它处理业务逻辑,如按下按钮和处理逻辑,第二个是视图(片段)。

之后您可以使用

app:onRefreshListener="@{() -> yourViewFragment.refreshList()}"

如果当前没有订阅视图,请避免出现"上下文泄漏"或无法正常工作的解决方案。

由于 onRefreshListener 绑定到片段,因此可以将其传递到片段中。

您需要在 ViewModel 中创建一个 LiveData 或 ObservableField 来处理此类操作,因为如果您暂停并恢复片段,您将再次观察 LiveData。这也意味着您将再次获得最后的数据。

可以在视图模型中使用的示例:

<Textview ... name="@{viewModel.dataOfYourModel}" onClick="@{viewModel.doNetworkCall}" />

黄金法则:每个以 android.* 开头的包/导入都不应该在视图模型中,除了 android.arch.* 组件。

最新更新