首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从分页源或远程中介库调用不同的api资源

如何从分页源或远程中介库调用不同的api资源
EN

Stack Overflow用户
提问于 2021-10-27 21:58:49
回答 1查看 938关注 0票数 0

嘿,我想为我的寻呼库3调用两个不同的api。我想问一下,什么是最适合我使用寻呼源远程中介?两者的用例是什么?谁能解释一下。

第一次api调用的仅适用于一次

代码语言:javascript
复制
@GET("/movie?min=20")

上面的api调用返回此响应

代码语言:javascript
复制
data class movie(
  var id: Int?,
  var name: String?,
  var items : List<Genre>?
}

现在为第二个api调用它的循环一次又一次地调用

代码语言:javascript
复制
@GET("/movie?count=20&&before={time}")

上面的api调用返回以下内容

代码语言:javascript
复制
data class movie(
  var items : List<Genre>?
}

体裁

代码语言:javascript
复制
data class Genre(
   var type: String?,
   var date: String?,
   var cast: String?
}

类型在两个api调用中都有数据。我试着用谷歌搜索并找到了这个示例。但是在这个内部,两个api都返回相同的数据。但在我的例子中,两者的结果有点不同。另外,id,名称仅在UI中使用,组件列表将转到适配器。但我不知道怎么做到这一点。我是Flow的新手,很难理解,老实说,我正在努力学习CodeLab。另一件重要的事情是,当第一次api调用,其中最后一项包含日期将发送到时间参数中的第二个api调用,然后第二个api最后一个项目日期再次调用第二个api时,这将是循环的。那么,我如何在循环条件下再次跟踪它。第三我想在列表的顶部更新数据,我们能在内存中存储数据,而不是更新列表上的值吗?谢谢你提前。对不起,我的英语错了。

更新

在@dlam建议之后,我试着练习一些代码

MainActivity

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private val viewModel by viewModels<ActivityViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        lifecycleScope.launchWhenCreated {
            viewModel.getMovie().collectLatest {
//                setupAdapter()
            }
        }

    }
}

ActivityViewModel

代码语言:javascript
复制
class ActivityViewModel(app: Application) : AndroidViewModel(app) {

    fun getMovie(): Flow<PagingData<Genre>> {
        return Pager(
            config = PagingConfig(
                pageSize = 20
            ),
            pagingSourceFactory = {
                MultiRequestPagingSource(DataSource())
            }
        ).flow
    }
}

MultiRequestPagingSource

代码语言:javascript
复制
class MultiRequestPagingSource(private val dataSource: DataSource) : PagingSource<String, Genre>() {

    override fun getRefreshKey(state: PagingState<String, Genre>): String? {
        return state.anchorPosition?.let { anchorPosition ->
            state.closestPageToPosition(anchorPosition)?.nextKey
        }
    }

    override suspend fun load(params: LoadParams<String>): LoadResult<String, Genre> {
        val key = params.key ?: ""

        return try {
            val data = when (params) {
                is LoadParams.Refresh -> {
                    dataSource.fetchInitialMovie()
                }
                is LoadParams.Append -> {
                    dataSource.fetchMovieBefore(key)
                }
                is LoadParams.Prepend -> null
            }

            LoadResult.Page(
                data = data.result,
                prevKey = null,
                nextKey = data?.nextKey,
            )
        } catch (exception: IOException) {
            LoadResult.Error(exception)
        }
    }
}

我在data = data.result上出错了

代码语言:javascript
复制
Type mismatch.
Required:
List<TypeVariable(Value)>
Found:
ArrayDeque<Genre>?

DataSource

代码语言:javascript
复制
package com.example.multirequestpaging

class DataSource {

    data class MovieResult(
        val result: ArrayDeque<Genre>?,
        val nextKey: String?
    )

    fun fetchInitialMovie(): MovieResult {
        val response = ApiInterface.create().getMovieResponse(20)

        return MovieResult(
            addInArrayDeque(response),
            response.items?.last()?.date
        )
    }

    fun fetchMovieBefore(key: String): MovieResult {
        val response = ApiInterface.create().getMovieResponseBefore(20, key)

        return MovieResult(
            addInArrayDeque(response),
            response.items?.last()?.date
        )
    }

    private fun addInArrayDeque(response: MovieResponse): ArrayDeque<Genre> {
        val result: ArrayDeque<Genre> = ArrayDeque()
        response.items?.forEach {
            result.add(it)
        }

        return result
    }

}

获得完整代码项目链接

1. --我想在列表的顶部添加一个项目。如何使用使函数失效?对不起,我不知道我能用在哪里。

2.我想使用id,在其他地方命名,所以如何在活动类中获得这些变量值。

3.是我的代码结构好吗?我需要改进吗,请举个例子。它也将帮助初学者,谁正在学习寻呼图书馆。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-29 05:32:34

PagingSource是分页的主要驱动程序,它负责加载显示的项,并表示数据真相的单一来源。

RemoteMediator用于分层源,它本质上是一个回调,当PagingSource耗尽数据时触发该回调,因此您可以从辅助源中获取。这主要适用于这样的情况:从DB + Network中获取数据,希望本地缓存的数据支持分页,然后使用RemoteMediator作为回调从网络获取更多的项到缓存中。

在这个场景中,您有两个API,但是它们都是从同一个网络源获取的,所以这里只需要PagingSource。如果我的理解是正确的,您基本上希望在初始加载时调用第一个API,在随后的预置/附加页面加载时调用第二个API,您可以根据获得的LoadParams类型检查/打开该API。参见此处的子类型:https://developer.android.com/reference/kotlin/androidx/paging/PagingSource.LoadParams

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69745942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档