【问题标题】:Best practices and patterns in ViewModel + Data Binding. Is ObservableField in ViewModel OK?ViewModel + 数据绑定中的最佳实践和模式。 ViewModel 中的 ObservableField 可以吗?
【发布时间】:2017-10-11 19:34:34
【问题描述】:

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

第一种方法:

  1. ViewModel 提供LiveData
  2. Activity 订阅 LiveData
  3. 当名为 Activity 的观察者将数据设置为 ViewModel ObservableField
  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 中的 listLoading ObservableField 更新为这样:

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 返回状态。在这个sample from Google 中,数据被包装在Resource 对象中。

another sample app from Google使用第一种方法

我想向有更多使用 Android 数据绑定和 Android Arch 组件经验的开发人员了解这两种模式的优缺点。

【问题讨论】:

  • 关于这些问题的任何最终结论?我想使用第二种方法,但仍然感到困惑。有什么帮助吗??

标签: android design-patterns android-databinding android-architecture-components android-mvvm


【解决方案1】:

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

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

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

之后就可以使用了

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

如果当前没有订阅视图,请避免出现“上下文泄漏”或无效的解决方案。

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

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

可以在 ViewModel 中使用的示例:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 2011-07-22
    • 2011-09-22
    • 2014-09-13
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多