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

问题描述

我为其中一个包含LiveData列表的片段提供了一个AndroidViewModel,并且为另一个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,然后我通过`.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:

我创建了此扩展方法fun <T, R> LiveData<T>.switchMap(func: (T) -> LiveData<R>) = Transformations.switchMap(this, func)以使代码更具可读性.

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.

我还在我的资料库中创建了一个名为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()
    }

推荐答案

您需要switchMapselectedTeam上,并且可能重命名为"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中的选定项更改过滤LiveData列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 19:57