Как и где использовать Transformations.switchMap?

В недавней библиотеке компонентов архитектуры Android, выпущенной Google, у нас есть две статические функции в классе Transformations. Хотя функция map проста и легко понятна, мне трудно правильно понять функцию switchMap.

Официальную документацию по SwitchMap можно найти , android.arch.core.util.Function>) rel=noreferrer>здесь.

Может кто-нибудь объяснить, как и где использовать функцию switchMap на практическом примере?

Ответ 1

В map() функция

LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
     return user.firstName + " " + user.lastName; // Returns String
});

каждый раз, когда значение userLiveData изменяется, userName также будет обновляться. Обратите внимание, что мы возвращаем String.

В функции switchMap():

MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
    repository.getUserById(id)); // Returns LiveData

void setUserId(String userId) {
     this.userIdLiveData.setValue(userId);
}

userIdLiveData раз, когда значение userIdLiveData изменяется, будет вызываться repository.getUserById(id), как функция map. Но repository.getUserById(id) возвращает LiveData. Поэтому каждый раз, когда значение LiveData возвращаемое repository.getUserById(id) изменяется, значение userLiveData будет меняться. Таким образом, значение userLiveData будет зависеть от изменений userIdLiveData и изменения значения repository.getUserById(id).

Практический пример switchMap(): представьте, что у вас есть профиль пользователя с кнопкой "следовать" и кнопкой "Следующий профиль", которая устанавливает другую информацию профиля. Следующая кнопка профиля вызовет setUserId() с другим идентификатором, поэтому userLiveData и изменится пользовательский интерфейс. Кнопка Follow вызовет DAO, чтобы добавить к этому пользователю еще одного подписчика, поэтому у пользователя будет 301 подписчик вместо 300. У userLiveData будет это обновление, которое поступает из репозитория, полученного из DAO.

Ответ 2

Добавив мои 2 цента к ответу @DamiaFuentes.

MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
repository.getUserById(id)); // Returns LiveData

void setUserId(String userId) {
     this.userIdLiveData.setValue(userId);
}

Метод Transformations.switchMap будет вызываться, только если у вас есть хотя бы один наблюдатель для userLiveData

Ответ 3

Для тех, кто хочет получить более подробное описание функции-переключателя @DamiaFuentes, приведенный ниже:

 MutableLiveData userIdLiveData = ...;
 LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
     repository.getUserById(id));

 void setUserId(String userId) {
      this.userIdLiveData.setValue(userId);
 }

В сценарии, где хранилище содержит User (1, "Jane") и User (2, "John"), когда значение userIdLiveData установлено в "1", switchMap вызовет getUser (1), который вернет LiveData содержащий значение User (1, "Jane"). Так что теперь userLiveData будет выдавать User (1, "Jane"). Когда пользователь в хранилище обновляется до User (1, "Sarah"), userLiveData автоматически уведомляется и отправляет User (1, "Sarah").

Когда метод setUserId вызывается с userId = "2", значение userIdLiveData изменяется и автоматически запускает запрос на получение пользователя с идентификатором "2" из хранилища. Итак, userLiveData испускает User (2, "Джон"). LiveData, возвращаемый repository.getUserById(1), удаляется как источник.

Из этого примера мы можем понять, что userIdLiveData является триггером, а LiveData, возвращаемый repository.getUserById, является "резервной" LiveData.

Для получения дополнительной информации, проверьте: https://developer.android.com/reference/android/arch/lifecycle/Transformations