Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 分页库3.0:如何将项目总数传递给列表标题?_Android_Kotlin_Android Recyclerview_Android Paging_Android Paging Library - Fatal编程技术网

Android 分页库3.0:如何将项目总数传递给列表标题?

Android 分页库3.0:如何将项目总数传递给列表标题?,android,kotlin,android-recyclerview,android-paging,android-paging-library,Android,Kotlin,Android Recyclerview,Android Paging,Android Paging Library,请帮帮我。 该应用程序仅用于接收来自的植物列表并在RecyclerView中显示。 我在这里使用的是分页库3.0。 任务:我想添加一个标题,其中将显示植物的总量。 问题:我就是找不到一种方法将总项目的值传递给标题 Data model: data class PlantsResponseObject( @SerializedName("data") val data: List<PlantModel>?, @Serial

请帮帮我。
该应用程序仅用于接收来自的植物列表并在RecyclerView中显示。
我在这里使用的是分页库3.0。
任务:我想添加一个标题,其中将显示植物的总量。
问题:我就是找不到一种方法将总项目的值传递给标题

    Data model:  
    data class PlantsResponseObject(
    @SerializedName("data")
    val data: List<PlantModel>?,
    @SerializedName("meta")
    val meta: Meta?
) {
    data class Meta(
        @SerializedName("total")
        val total: Int? // 415648
    )
}
   data class PlantModel(
    @SerializedName("author")
    val author: String?,
    @SerializedName("genus_id")
    val genusId: Int?, 
    @SerializedName("id")
    val id: Int?)
数据模型:
数据类PlantsResponseObject(
@SerializedName(“数据”)
val数据:列表?,
@序列化名称(“元”)
瓦尔·梅塔:梅塔?
) {
数据类元(
@序列化名称(“总计”)
val总计:整数?//415648
)
}
数据类模型(
@序列化名称(“作者”)
val作者:字符串?,
@序列化名称(“属id”)
val genusId:Int?,
@序列化名称(“id”)
valid:Int?)
数据源类:

class PlantsDataSource(
    private val plantsApi: PlantsAPI,
    private var filters: String? = null,
    private var isVegetable: Boolean? = false

) : RxPagingSource<Int, PlantView>() {

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, PlantView>> {
        val nextPageNumber = params.key ?: 1
           return plantsApi.getPlants(  //API call for plants
               nextPageNumber, //different filters, does not matter
               filters,
               isVegetable)
               .subscribeOn(Schedulers.io())
               .map<LoadResult<Int, PlantView>> {
                   val total = it.meta?.total ?: 0 // Here I have an access to the total count
 //of items, but where to pass it?
                    LoadResult.Page(
                       data = it.data!! //Here I can pass only plant items data
                           .map { PlantView.PlantItemView(it) },
                       prevKey = null,
                       nextKey = nextPageNumber.plus(1)
                   )
               }
               .onErrorReturn{
                   LoadResult.Error(it)
               }
    }

    override fun invalidate() {
        super.invalidate()
    }
}
类PlantsDataSource(
私人val plantsApi:plantsApi,
私有变量筛选器:字符串?=null,
私有变量:布尔?=false
):RxPagingSource(){
覆盖有趣的loadSingle(参数:LoadParams):Single{
val nextPageNumber=params.key?:1
返回plantsApi.getPlants(//plants的API调用
nextPageNumber,//不同的过滤器并不重要
过滤器,
(蔬菜)
.subscribeOn(Schedulers.io())
.地图{
val total=it.meta?.total?:0//在这里,我可以访问总计数
//物品的数量,但在哪里传递?
LoadResult.Page(
data=it.data!!//这里我只能传递工厂项目数据
.map{PlantView.PlantItemView(it)},
prevKey=null,
nextKey=nextPageNumber.plus(1)
)
}
A.报税表{
LoadResult.Error(it)
}
}
覆盖失效(){
super.invalidate()
}
}
页面只接受植物本身的列表。数据源之上的所有类(Repo、ViewModel、Activity)都无法访问响应对象。
问题:如何将项目总数传递到列表标题?

我将非常感谢您的帮助。

一种方法是使用MutableLiveData,然后观察它。比如说

val countPlants = MutableLiveData<Int>(0)

override fun loadSingle(..... {

    countPlants.postValue(it.meta?.total ?: 0)

} 

分页中的withHeader函数只返回一个
ConcatAdapter
,给定一个
LoadStateHeader
,它有一些代码要侦听,并根据适配器的
LoadState
进行更新

通过实现您自己的
ItemCountAdapter
,您应该能够做一些非常类似的事情,除了听
LoadState
更改之外,它听
adapter.itemCount
。您需要构建一个流/侦听器来决定何时发送更新,但您可以简单地将loadState更改映射到itemCount

请参见此处了解
LoadStateAdapter
代码,您基本上可以复制该代码,并将
loadState
更改为
itemCount

e、 g


在第一次尝试使用分页时面临同样的困境,尽管为分页目的进行计数,但它没有提供获取计数的方法(即
分页
库首先使用
计数(*)
检查项目是否多于或少于规定的
分页配置
值)在执行其余的查询之前,它可以完美地返回找到的结果总数)

目前实现这一点的唯一方法是并行运行两个查询:一个用于您的项目(正如您已经拥有的),另一个仅用于计算它使用与前一个相同的查询参数找到的结果的数量,但仅用于
count(*)

不需要将后者作为
PagingDataSource
返回,因为它会不必要地添加大量样板文件。只需将其作为正常的
LivedData
返回,这样每当列表结果发生变化时,它都会自动更新,否则,如果您返回一个普通的
整数,它可能会遇到列表大小变化的问题,并且在第一次加载后该值不会更新

设置好这两个适配器后,使用
ConcatAdapter
将它们添加到
RecyclerView
适配器中,并将前面提到的适配器的顺序与您希望它们在列表中显示的顺序相同


例如:如果希望计数显示在列表的开头/顶部,则首先使用计数适配器,然后使用列表项适配器设置
ConcatAdapter

您可以将
分页数据
类型更改为
配对
(或任何其他结构),以添加所需的任何信息。 然后,您将能够发送总计页面,并执行类似以下操作:

LoadResult.Page(
   data = it.data.map { Pair(PlantView.PlantItemView(it), total) },
   prevKey = null,
   nextKey = nextPageNumber.plus(1)
)
在您的
ModelView
中,执行任何操作,例如再次将其映射到
PlantItemView
,但使用
第二个
字段更新标题


确实,它不是很优雅,因为您在所有项目中都发送了它,但它比其他建议的解决方案要好。

adapter.itemCount与我的问题无关。植物的总量约为300000株,我想在30株植物的第一部分加载后立即在适配器中显示这个值。我在服务器响应中从元对象中提取了植物的总数。我明白了,如果我误读了您的问题,很抱歉。无论您如何填充/查询工厂总数,总体思路仍应相似。i、 例如,使用PagingDataAdapter+生成的ConcatAdapter与LoadStateAdapter非常相似,但定制为显示初始加载完成的时间,并且不是空的,而不是简单地侦听预结束/附加加载状态更新。如果有什么我可以澄清的,请告诉我。
abstract class ItemCountAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() { 

var itemCount: Int = 0

set(itemCount { ... }

open fun displayItemCountAsItem(itemCount: Int): Boolean { 
    return true 
}
fun PagingDataAdapter.withItemCountHeader(itemCountAdapter): ConcatAdapter {
    addLoadStateListener {
        itemCountAdapter.itemCount = itemCount
    }
    return ConcatAdapter(itemCountAdapter, this)
}
LoadResult.Page(
   data = it.data.map { Pair(PlantView.PlantItemView(it), total) },
   prevKey = null,
   nextKey = nextPageNumber.plus(1)
)