Android-根据ViewModel中的选定项更改过滤LiveData列表

时间:2019-01-01 11:09:21

标签: android kotlin android-livedata

我为我的片段之一提供了一个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()

    ...
}

注意: getAllTeamsgetAllPlayers返回RxJava Flowable List,然后我通过`.toLiveData将其转换为LiveData List。

当前,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 :(得分:2)

您需要在switchMapselectedTeam,并可能将其重命名为“ 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 
    }

我真的希望它能像我在这里直接写的那样起作用。