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

Hay*_*den 1 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()

    ...
}
Run Code Online (Sandbox Code Playgroud)

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

目前,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()
Run Code Online (Sandbox Code Playgroud)

但是,您可能会猜到也可能不会猜到,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()
    }
Run Code Online (Sandbox Code Playgroud)

Epi*_*rce 5

您需要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 
    }
Run Code Online (Sandbox Code Playgroud)

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