【问题标题】:Chain a request in retrofit using rxJava2 and populate the result in recyclerview使用 rxJava2 在改造中链接请求并将结果填充到 recyclerview
【发布时间】:2019-02-07 06:32:40
【问题描述】:

我正在尝试使用来自 thesportsdb 的 API 来显示特定联赛的最后一场比赛。在我的 recyclerview 中,我想显示每个团队的团队徽章,但是当我请求 lastmatch API 时,它不包括团队徽章,只有每个团队的 id,如果我想显示徽章,它需要我请求团队包含团队徽章网址的个人资料。

由于我是 rxJava 的新手,所以我仍然熟悉它。有些帖子建议使用平面地图,但对于像我这样的初学者来说实施起来有点困难。

这是改造服务:

interface FootballRest {

@GET("eventspastleague.php")
fun getLastmatch(@Query("id") id:String) : Flowable<FootballMatch>

@GET("lookupteam.php")
fun getTeam(@Query("id") id:String) : Flowable<Teams>
}

我使用了存储库模式

class MatchRepositoryImpl(private val footballRest: FootballRest) : MatchRepository {
override fun getFootballMatch(id: String): Flowable<FootballMatch> = footballRest.getLastmatch(id)

override fun getTeams(id: String): Flowable<Teams> = 
footballRest.getTeam(id)
}

这是进行调用并将数据发送到视图的演示者:

class MainPresenter(val mView : MainContract.View, val matchRepositoryImpl: MatchRepositoryImpl) : MainContract.Presenter{

val compositeDisposable = CompositeDisposable()

val requestMatch = matchRepositoryImpl.getFootballMatch("4328")
val requestTeam = matchRepositoryImpl.getTeams()

override fun getFootballMatchData() {
    compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328")
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe{
                mView.displayFootballMatch(it.events)
            })
}

到目前为止,我只显示最后一场比赛结果,但我还想在名单上显示徽章球队。

【问题讨论】:

    标签: android kotlin retrofit2 rx-java2


    【解决方案1】:

    与使用blockingGet 运算符相比,您可能更容易使用平面地图并将所有这些数据作为单个流返回。

    您可以通过组合 flatmapzip 运算符来实现此目的。这看起来像下面这样,其中 MatchData 保存 FootballMatch 数据以及主队和客队数据。

    data class MatchData(val footballMatch: FootballMatch, val homeTeam: Teams, val awayTeam: Teams)
    

    然后,您的平面地图操作需要为主队和客队调用 getTeams 方法,然后可以通过 zip 运算符将其与 footballMatch 数据结合。

    override fun getFootballMatchData() {
        compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328")
                .subscribeOn(Schedulers.io())
                .flatMap { footballMatch ->
                    Flowable.zip(
                            matchRepositoryImpl.getTeams(footballMatch.idHomeTeam),
                            matchRepositoryImpl.getTeams(footballMatch.idAwayTeam),
                            BiFunction { homeTeam: Teams, awayTeam: Teams ->
                                MatchData(
                                        footballMatch = footballMatch,
                                        homeTeam = homeTeam,
                                        awayTeam = awayTeam)
                            }
                    )
                }
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    mView.displayFootballMatch(it)
                })
    }
    

    【讨论】:

      【解决方案2】:

      您可以将map 运算符与lastElement().blockingGet() 组合用于第二个Observable,然后返回Pair 的结果。一个简单的例子可以如下:

      @Test
      public fun test1() {
          Observable.just(1)
                  .map {
                      // here 'it' variable is calculated already so it can be passed to the second observable
                      val result = Observable.just(2).lastElement().blockingGet()
                       Pair<Int, Int>(it, result)
                  }
                  .subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe { t -> System.out.println("First : " + t?.first + ", second : " + t?.second) }
      
          Thread.sleep(1000)
      }
      

      输出

      1 2

      如果您的第二个Observable 取决于第一个的结果,那么只需在map 运算符中使用it 变量并将其传递到所需的任何位置。因此,如果使用前面的示例,您的代码可以转换为:

      override fun getFootballMatchData() {
          compositeDisposable.add(matchRepositoryImpl.getFootballMatch("4328").toObservable( 
                  .map {
                      // here 'it' variable is calculated already so it can be passed to the second observable
                      val next = matchRepositoryImpl.getTeams(it).toObservable().lastElement().blockingGet()
                      Pair<Int, Int>(it, next)
                  }
                  .subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe{ t ->
                      mView.displayFootballMatch(t.first)
                      mView.displayBadgeTeam(t.second)
                  })
      }
      

      【讨论】:

      • 感谢您的回答,但为了调用 getTeam 函数,我需要传递一个应该从 getFootballMatch 函数发出的 id 参数
      • 谢谢,你的答案我没试过,试过了我会尽快更新答案
      猜你喜欢
      • 1970-01-01
      • 2017-09-07
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多