-1

I created a library here: https://github.com/chanjungkim/ALiveData

This library is made because of MutableLiveData<ArrayList<T>>. Many people who learns about LiveData complains or they are confused with this type when they need to manipulate(add, remove, etc) the MutableLiveData. That's because ArrayList is easy to manipulate and _arrayList.value!!.add(item) or _arrayList.value!!.remove(0) seems to notify. But they don't.

At the end, when we want to notify, we must assign a value like _arrayList.value!! = mList. ArrayList and List both need to set the data like _arrayList.value!! = mArrayList or _arrayList.value!! = mList.

My question is List doesn't have add(), remove(), etc. On the other hand, ArrayList already has those functions and helps us manipulate the list much easier.

some people suggested like this

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

So, what's the point of using List over ArrayList? Could you give me example with the explanation of using it?

c-an
  • 3,543
  • 5
  • 35
  • 82
  • Why not simply `MutableLiveData>` if you want it to be mutable at all times? The point is in the intention, and being implementation agnostic. If you have `List` you can use an `AwesomeList` for it. When you have `ArrayList`, you can't use anything but an ArrayList. – Shark Jun 18 '21 at 15:06
  • In the end, you should have a "hidden" MutableLiveData, and an "exposed" LiveData with a custom getter that returns the Mutable version. So that you can't put things in there from the consumer side. So an exposed `LiveData>` could work with a hidden `MutableLiveData>`. – Shark Jun 18 '21 at 15:08

2 Answers2

1

A List is an interface, and defines the methods that must be implemented by any classes that would like to behave like a list. It can be considered the 'most basic' version of a list, and only defines the minimum requirements for an implementing class to behave like a list.

In the same way, the List interface itself extends the Collections interface, which in turn extends the Iterable interface. Each one adds more functionality to the one before it... kind of like lego blocks stacked on top of each other, creating more complex shapes.

An ArrayList is a class, which implements MutableList (which itself implements List). This means that an ArrayList can be instantiated, and passed around as an actual object. Because of this object oriented design, and according to the Liskov substitution principle, any class (or interface) can be replaced by a subclass (or class implementing the interface) interchangeably.

This is a fundamental principle to object oriented design. It helps break parts of the application down into smaller, more basic and more manageable pieces, and then grow as required.

To answer your question more specifically, if the class that is observing the LiveData only cares about the methods defined in the List interface, then that is the all it requires to know about the value. The actual value could in fact be an ArrayList, a MutableList or even a custom class MyOwnFancyList<E>: List<E>, it does not matter to the observer, just as long as it implements the List interface.

Ryan
  • 948
  • 6
  • 20
  • Well, This is not my answer. My question is not about how flexible List is but why should we use it in the LiveData. There's no reason to use customised subclass of List interface. – c-an Jun 19 '21 at 04:25
  • Hi @c-an, after re-reading your question I think I understand better what you are asking. I have written a second answer - let me know if this is more in line with what you are looking for. – Ryan Jun 22 '21 at 00:26
1

LiveData can be used in different ways, and of course there is no one correct way, but a very common way of using it is within the Android MVVM architecture recommended by Google for use in Android apps.

In this architecture, the Activity (or Fragment) observe the LiveData of the ViewModel. When doing this, the goal would be to make the UI as 'dumb' as possible, where you try to handle as much of the app logic and behaviour in the ViewModel, and the Activity simply observes and reflects it on the UI.

In a case like this, it is often preferable for the values of the LiveData being observed to be immutable.

By doing this, it limits the Activity from being able to manipulate the data it is observing, such as add()ing or remove()ing anything from it. As just described, the goal should be to limit the UI's ability to make exactly these type of changes. If the Activity wants to add() an item to an ArrayList that it is observing, it should instead do this by calling a method on the ViewModel, which will in turn update it's own LiveData.value to the new, updated list, which will in turn be observed by the Activity and updated on the UI.

By only allowing the Activity to observe the immutable values, it helps enforce this separation of concerns, and limits any accidental 'leak' of logic into the Activity itself.

This idea can be extended further by ensuring that the observed values are of type LiveData, and not MutableLiveData. Using the latter can allow the Activity to manipulate the live data on its own, and break the MVVM pattern.

Ryan
  • 948
  • 6
  • 20