Android - Фильтровать список LiveData на основе изменения выбранного элемента в ViewModel - PullRequest
0 голосов
/ 01 января 2019

У меня есть AndroidViewModel для одного из моих фрагментов, который содержит список LiveData, и у меня есть другое свойство для выбранного элемента другого списка LiveData.Ниже приведен пример того, о чем я говорю:

class TeamViewModel(app: Application): AndroidViewMode(app) {
    ...

    val selectedTeam = MutableLiveData<Team>()

    val allTeams: LiveData<List<Team>>
        get() = repository.getAllTeams().toLiveData()

    val allPlayers: LiveData<List<Player>>
        get() = repository.getAllPlayers().toLiveData()

    ...
}

Примечание: getAllTeams и getAllPlayers возвращают RxJava Flowable List, который я затем преобразовываю в LiveDataСписок через `.toLiveData

В настоящее время allPlayers представляет всех игроков из всех команд.Я бы хотел, чтобы при изменении значения selectedTeam значение allPlayers отфильтровывалось для отображения только игроков с selectedTeam.

. Я пытался фильтровать allPlayers прямо так:

val allPlayers: LiveData<List<Player>>
    get() = repository.getAllPlayers()
                .flatMap { list -> Flowable.fromIterable(list)
                    .filter {
                        player -> player.team == selectedTeam.value?.team
                    }
                }
                .toList()
                .toFlowable()
                .toLiveData()

Но, как вы можете или не можете догадаться, он не обновляет фильтр для allPlayers всякий раз, когда selectedTeam изменяется.

Есть ли в любом случаединамически менять фильтр для allPlayers всякий раз, когда selectedTeam изменяется?

РЕДАКТИРОВАТЬ

Благодаря @EpicPandaForce, окончательное решение, которое я придумал, выглядит следующим образом:

Я создал этот метод расширения fun <T, R> LiveData<T>.switchMap(func: (T) -> LiveData<R>) = Transformations.switchMap(this, func), чтобы сделать код более читабельным.

Я также создал функцию в своем хранилище под названием getAllPlayersFromTeam(team: Team), которая, как указывает функция, получает всеигроки из команды.

Наконец, это конечный результат моей собственности:

val allPlayersFromSelectedTeam: LiveData<List<Player>>
    get() = selectedTeam.switchMap { 
        repository
            .getAllPlayersFromTeam(it)
            .toLiveData()
    }

1 Ответ

0 голосов
/ 02 января 2019

Вам нужно switchMap вместо selectedTeam и, возможно, переименовать в "allPlayers", потому что это ложь.: P

val selectedTeam = MutableLiveData<Team>()

val allTeams: LiveData<List<Team>>
    get() = repository.getAllTeams().toLiveData()

val playersOfSelectedTeam: LiveData<List<Player>>
    get() = Transformations.switchMap(selectedTeam) { team ->
         val allPlayers = repository.getAllPlayers().toLiveData()
         val players = when {
             team == null -> allPlayers
             else -> {
                 Transformations.switchMap(allPlayers) { playerList ->
                     val filteredPlayers = MutableLiveData<List<Player>>()
                     val filteredList = playerList.filter { player -> player.team == team }
                     filteredPlayers.value = filteredList
                     filteredPlayers
                 }
             }
         }
         players 
    }

Что я действительно надеюсь, что это работает, так как я написал это прямо здесь.

...