简体   繁体   English

Android - 根据 ViewModel 中的 Selected Item 更改过滤 LiveData 列表

[英]Android - Filter LiveData List based on Selected Item change in ViewModel

I have a AndroidViewModel for one of my fragments which contains a LiveData List, and I have another property for selected item of another LiveData List.我的其中一个片段有一个 AndroidViewModel,其中包含一个 LiveData 列表,并且我有另一个 LiveData 列表的选定项目的另一个属性。 Below is an example of what I am talking about:下面是我正在谈论的一个例子:

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()

    ...
}

Note: getAllTeams and getAllPlayers returns a RxJava Flowable List, which I then convert to LiveData List via .toLiveData注意: getAllTeamsgetAllPlayers返回一个 RxJava Flowable List,然后我通过.toLiveData将其转换为 LiveData List

Currently, allPlayers represents all the players from all teams.目前, allPlayers代表所有球队的所有球员。 I'd like to make it so that whenever the value of selectedTeam changes, that allPlayers gets filtered down to only display players from the selectedTeam .我想这样做,以便每当selectedTeam的值发生变化时, allPlayers都会被过滤为仅显示来自selectedTeam球员。

What I've tried is to filter allPlayers directly like so:我尝试过的是像这样直接过滤allPlayers

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

But as you may or may not guess, it doesn't update the filter for allPlayers whenever selectedTeam changes.但是正如您可能会也可能不会猜到的那样,它不会在selectedTeam更改时更新allPlayers的过滤器。

Is there anyway to dynamically change the filter for allPlayers whenever selectedTeam changes?无论如何,每当selectedTeam发生变化时,是否可以动态更改allPlayers的过滤器?

EDIT编辑

Thanks to @EpicPandaForce, the final solution I came up with is as followed:感谢@EpicPandaForce,我想出的最终解决方案如下:

I created this extension method:我创建了这个扩展方法:

fun <T, R> LiveData<T>.switchMap(func: (T) -> LiveData<R>) = Transformations.switchMap(this, func)

to make the code more readable.使代码更具可读性。

I've also created a function in my repository called getAllPlayersFromTeam(team: Team) which, as the function specifies, gets all the players from a team.我还在我的存储库中创建了一个名为getAllPlayersFromTeam(team: Team)的函数,正如该函数指定的那样,它可以获取团队中的所有球员。

Finally this is the end result of my property:最后这是我的财产的最终结果:

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

You need to switchMap over the selectedTeam , and possibly renamed "allPlayers" because that's a lie.您需要switchMapselectedTeam ,并可能改名为“allPlayers”,因为这是一个谎言。 :P :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 
    }

Which I really hope it works as I wrote it here directly.我真的希望它能像我直接在这里写的那样工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM