android - 通过改造和分页进行多个 Api 调用
问题描述
我正在尝试使用带有改造的分页。但是我必须多次调用过滤或更改流动站(它是美国国家航空航天局的图片应用程序)。但是我的应用程序每秒都会调用 Api,这会导致它崩溃。我用 livedata 也用 flow 试过,但没有用。
使用 View Pager 在选项卡布局中有三个片段执行相同的流程,它们是curiousFragment、SpiritFragment、OpportunityFragment
object RetrofitInstance {
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi)).baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
val api : SimpleApi by lazy {
retrofit.create(SimpleApi::class.java)
}}
interface SimpleApi {
@GET("mars-photos/api/v1/rovers/{name}/photos?sol=1000&api_key=DEMO_KEY")
fun getPhotos(@Path("name") name : String,
@Query("per_page")per_page:Int?,
@Query("page") page: Int):
Single<AllPhotos>
class DataSource(name:String) : RxPagingSource<Int,Photo>(){
var name :String
init{
this.name = name
}
override fun getRefreshKey(state: PagingState<Int, Photo>): Int? {
return null
}
override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Photo>> {
val page = params.key ?:1
return RetrofitInstance.api.getPhotos(name,params.loadSize,page)
.subscribeOn(Schedulers.io())
.map {toLoadResult(it,page)}
.onErrorReturn { LoadResult.Error(it) }
}
private fun toLoadResult(data: AllPhotos,page : Int):LoadResult<Int,Photo>{
return LoadResult.Page(
data = data.photos,
prevKey = if(page==1) null else page-1,
nextKey = page.plus(1)
)
}
}
class ViewModelDataSource (application: Application):AndroidViewModel(application) {
fun getPhotosLiveData(name : String):LiveData<PagingData<Photo>>{
return Pager(
config = PagingConfig(pageSize = 10),
pagingSourceFactory = {
DataSource(name)
},
).liveData
}
}
class CuriosityFragment : Fragment() {
private lateinit var binding:FragmentCuriosityBinding
lateinit var mApiViewModel : ViewModelDataSource
private lateinit var curiosityAdapter: AdapterCuriosity
var hasLoadedOnce = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentCuriosityBinding.inflate(inflater,container,false)
mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
setupRecyclerView()
loaddata()
return binding.root
}
fun setupRecyclerView(){
curiosityAdapter = AdapterCuriosity()
binding.recyclerViewCriosity.apply {
adapter = curiosityAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
fun loaddata(){
mApiViewModel.getPhotosLiveData("curiosity").observe(viewLifecycleOwner, Observer {
curiosityAdapter.submitData(this.lifecycle,it)})
}
class OpportunityFragment : Fragment() {
private lateinit var binding: FragmentOppurtunityBinding
private lateinit var mApiViewModel: ViewModelDataSource
private lateinit var recyclerView: RecyclerView
private lateinit var opportunityAdapter:AdapterOpportunity
var hasLoadedOnce = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentOppurtunityBinding.inflate(inflater, container, false)
recyclerView = binding.recyclerViewOpportunity
mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
setupRecyclerView()
loaddata()
setHasOptionsMenu(true)
return binding.root
}
fun setupRecyclerView(){
opportunityAdapter = AdapterOpportunity()
binding.recyclerViewOpportunity.apply {
adapter = opportunityAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
fun loaddata(){
mApiViewModel.getPhotosLiveData("opportunity").observe(viewLifecycleOwner, Observer {
opportunityAdapter.submitData(this.lifecycle,it)})
}
class SpiritFragment : Fragment() {
private lateinit var binding: FragmentSpiritBinding
private lateinit var mApiViewModel : ViewModelDataSource
private lateinit var spiritAdapter:AdapterSpirit
lateinit var recyclerView: RecyclerView
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSpiritBinding.inflate(inflater, container, false)
recyclerView = binding.recyclerViewSpirit
mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
setupRecyclerView()
loaddata()
setHasOptionsMenu(true)
return binding.root
}
fun setupRecyclerView(){
spiritAdapter = AdapterSpirit()
binding.recyclerViewSpirit.apply {
adapter = spiritAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
fun loaddata(){
mApiViewModel.getPhotosLiveData("spirit").observe(viewLifecycleOwner, Observer {
spiritAdapter.submitData(this.lifecycle,it)})
}
解决方案
推荐阅读
- python - 我们可以在不为 Elasticsearch 指定文档 ID 的情况下进行批量更新吗?
- python - 如何返回neo4j中所有子图的子节点数?
- c# - 通过 owin 自托管的 api 与 windows 服务通信
- list - 通过单击 Flutter 中的按钮,使用列表中的数据构建新容器
- python - 除了 Jupyter Notebook,Anaconda 还需要安装到 PC 上吗?
- python - 为什么 python numpy sum() 给出的值与 + 不同?
- ios - 使用 XCode 12 和模拟器崩溃弹出窗口
- dynamic - APEX:将值传递给模态页面,设置为 Null,提交导致问题
- python - 无法在 Windows 上的 conda Python 3.8.3 环境中使用 pipenv 创建虚拟环境
- python - 图论 - 将 3D 空间中的点与其他三个最近点连接(基于距离)