繁体   English   中英

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

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

我的其中一个片段有一个 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()

但是正如您可能会也可能不会猜到的那样,它不会在selectedTeam更改时更新allPlayers的过滤器。

无论如何,每当selectedTeam发生变化时,是否可以动态更改allPlayers的过滤器?

编辑

感谢@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()
    }

您需要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 
    }

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

暂无
暂无

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

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