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

可紊 提交于 2020-01-29 05:46:16

问题


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

    ...
}

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

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.

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

But as you may or may not guess, it doesn't update the filter for allPlayers whenever selectedTeam changes.

Is there anyway to dynamically change the filter for allPlayers whenever selectedTeam changes?

EDIT

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

Finally this is the end result of my property:

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

回答1:


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.



来源:https://stackoverflow.com/questions/53994960/android-filter-livedata-list-based-on-selected-item-change-in-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!