MutableLiveData<ArrayList<T>> 对比 MutableLiveData<List<T>>。为什么要在这里使用List?

MutableLiveData<ArrayList<T>> vs MutableLiveData<List<T>>. Why should we use List here?

我在这里创建了一个库:https://github.com/chanjungkim/ALiveData

这个库是因为 MutableLiveData<ArrayList<T>> 而制作的。许多了解 LiveData 的人在需要操作(添加、删除等)MutableLiveData 时抱怨或对这种类型感到困惑。那是因为 ArrayList 易于操作,并且 _arrayList.value!!.add(item)_arrayList.value!!.remove(0) 似乎会通知。但他们没有。

最后,当我们要通知的时候,我们必须赋值,如_arrayList.value!! = mList。 ArrayList 和 List 都需要设置数据,如 _arrayList.value!! = mArrayList_arrayList.value!! = mList.

我的问题是 List 没有 add()、remove() 等。另一方面,ArrayList 已经有了这些函数,可以帮助我们更轻松地操作列表。

有人这样建议

_list.value = list.value.toMutableList().doWhatever().toList()

那么,使用 List 而不是 ArrayList 有什么意义呢?能否举例说明使用方法?

A List 是一个接口,它定义了任何 class 必须实现的方法,这些方法要表现得像一个列表。它可以被认为是列表的 'most basic' 版本,并且只定义了实现 class 表现得像列表的最低要求。

同理,List接口本身扩展了Collections接口,后者又扩展了Iterable接口。每一个都为前一个添加了更多功能……有点像乐高积木堆叠在一起,创造出更复杂的形状。

一个 ArrayList 是一个 class,它实现了 MutableList(它本身实现了 List)。这意味着 ArrayList 可以被实例化,并作为实际对象传递。由于这种面向对象的设计,并且根据 Liskov substitution principle,任何 class(或接口)都可以替换为子 class(或 class 实现接口)可互换.

这是面向对象设计的基本原则。它有助于将应用程序的各个部分分解为更小、更基本和更易于管理的部分,然后根据需要进行扩展。

更具体地回答你的问题,如果观察 LiveData 的 class 只关心 List 接口中定义的方法,那么这就是它需要知道的关于价值。实际值实际上可以是 ArrayListMutableList 甚至自定义 class MyOwnFancyList<E>: List<E>,这对观察者来说并不重要,只要它实现了 List接口。

LiveData可以有不同的使用方式,当然没有一种正确的使用方式,但是一种非常常见的使用方式是在Android MVVM architecture recommended by Google中使用在[=43=中] 应用程序。

在此架构中,Activity(或片段)观察 ViewModel 的 LiveData。这样做时,目标是使 UI 尽可能成为 'dumb',您尝试在 ViewModel 中处理尽可能多的应用程序逻辑和行为,而 Activity 只是观察并反映在 UI.

在这种情况下,观察到的 LiveData 的值通常最好 不可变。

通过这样做,它限制了 Activity 能够操纵它正在观察的数据,例如 add()ing 或 remove()ing 任何来自它的数据。正如刚才所描述的,目标应该是 限制 UI 进行这些类型更改的能力。 如果 Activity 想要 add() 一个项目到它正在观察的 ArrayList ,它应该通过调用 ViewModel 上的方法来做到这一点,这将反过来更新它自己的 LiveData.value到新的更新列表,Activity 将依次观察并在 UI.

上更新

通过只允许 Activity 观察不可变值,它有助于加强这种关注点分离,并将任何意外的 'leak' 逻辑限制在 Activity 本身中。

可以通过确保观测值的类型为 LiveData 而不是 MutableLiveData 来进一步扩展这个想法。使用后者可以让 Activity 自行操作实时数据,并打破 MVVM 模式。