Android - 根据 ViewModel 中的 Selected Item 更改过滤 LiveData 列表 [英] Android - Filter LiveData List based on Selected Item change in ViewModel

查看:25
本文介绍了Android - 根据 ViewModel 中的 Selected Item 更改过滤 LiveData 列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个片段有一个 AndroidViewModel,其中包含一个 LiveData 列表,并且我有另一个属性用于另一个 LiveData 列表的选定项目.下面是我正在谈论的一个例子:

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

    ...
}

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

Note: getAllTeams and getAllPlayers returns a RxJava Flowable List, which I then convert to LiveData List via .toLiveData

目前,allPlayers 代表所有球队的所有球员.我想这样做,每当 selectedTeam 的值发生变化时,allPlayers 都会被过滤掉,只显示来自 selectedTeam 的玩家.

Currently, allPlayers represents all the players from all teams. 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.

我尝试过的是像这样直接过滤allPlayers:

What I've tried is to filter allPlayers directly like so:

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 的过滤器.

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?

编辑

感谢@EpicPandaForce,我想出的最终解决方案如下:

Thanks to @EpicPandaForce, the final solution I came up with is as followed:

我创建了这个扩展方法:

I created this extension method:

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

使代码更具可读性.

我还在我的存储库中创建了一个名为 getAllPlayersFromTeam(team: Team) 的函数,正如函数指定的那样,它可以获取团队中的所有球员.

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.

最后这是我的财产的最终结果:

Finally this is the end result of my property:

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

推荐答案

您需要在 selectedTeamswitchMap,并且可能重命名为allPlayers",因为那是谎言.:P

You need to switchMap over the selectedTeam, and possibly renamed "allPlayers" because that's a lie. :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.

这篇关于Android - 根据 ViewModel 中的 Selected Item 更改过滤 LiveData 列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆