我正在尝试将新的Paging Library
和Room
用作数据库,但是我遇到了一个问题,该数据库返回的PagedList
应该不是相同的列表发送到UI之前,我map
在向用户显示之前需要一些实体,并且在此map
操作期间,我更改了列表大小(添加项),显然Paging Library
不支持此功能之类的操作,因为当我尝试运行应用程序时出现此异常:
Caused by: java.lang.IllegalStateException: Invalid Function 'function_name' changed return size. This is not supported.
查看分页库源代码,您会看到以下方法:
static <A, B> List<B> convert(Function<List<A>, List<B>> function, List<A> source) {
List<B> dest = function.apply(source);
if (dest.size() != source.size()) {
throw new IllegalStateException("Invalid Function " + function
+ " changed return size. This is not supported.");
}
return dest;
}
在您将动态项目添加到PagedList
之前,有没有解决的方法或需要处理的东西?
这就是我在做的
DAO
@Query("SELECT * FROM table_name")
fun getItems(): DataSource.Factory<Int, Item>
LocalSource
fun getItems(): DataSource.Factory<Int, Item> {
return database.dao().getItems()
.mapByPage { map(it) } // This map operation changes the list size
}
答案 0 :(得分:0)
我遇到同样的问题,仍在寻找更好的解决方案。
就我而言,在每个用户从API加载之前,我必须显示 1部分,这是我的解决方法。
class UsersViewModel : ViewModel() {
var items: LiveData<PagedList<RecyclerItem>>
init {
...
items = LivePagedListBuilder<Long, RecyclerItem>(
sourceFactory.mapByPage { it -> mapUsersToRecyclerItem(it) }, config).build()
}
private fun mapUsersToRecyclerItem(users: MutableList<User>): List<RecyclerItem> {
val numberOfSection = 1
for (i in 0 until numberOfSection) {
users.add(0, User()) // workaround, add empty user here
}
val newList = arrayListOf<RecyclerItem>()
newList.add(SectionItem())
for (i in numberOfSection until users.size) {
val user = users[i]
newList.add(UserItem(user.login, user.avatarUrl))
}
return newList
}
}
我当前的用户类别
data class User(
@SerializedName("login")
val login: String,
@SerializedName("id")
val id: Long = 0,
@SerializedName("avatar_url")
val avatarUrl: String
) {
constructor() : this("", 0, "")
}
当然,要显示Section
,我将有另一种方法不将其添加到RecyclerView data list
中(仅使用位置),但是在我的情况下,用户可以从列表中删除项目,因此使用位置可能会很困难处理
实际上,我回滚了使用旧负载的更多方式(使用EndlessRecyclerViewScrollListener),但希望对您有所帮助
答案 1 :(得分:0)
我想我已经找到了解决方法。
尽管这是一种变通方法,但对我来说却是有效的。
就我而言,我试图为这样的名称创建一个按字母顺序排列的列表:
**A - HeaderItem**
Aaron - Item
Anny - Item
**B - HeaderItem**
Bob - Item
Bil
**C - HeaderItem**
....
ROOM中的项目当然只是名称,当我尝试映射分页的项目并添加节标题时,它会更改列表大小,并且出现相同的错误。
我所做的是,HeaderItem对象包装了一个这样的Item:
首先,所有Item都实现了ListItem接口
interface ListItem{
const val HEADER = 0
const val ITEM = 1
fun getItemType() : Int
}
然后标题项目如下所示
class HeaderItem(val headerTitle : String, val item : Item) : ListItem {
@override
fun getItemType() : Int {
return ListItem.HEADER
}
}
然后,当我映射项目时,添加HeaderItem时,它将包含一个Item,这样映射的PagedList大小不会改变。现在我没有得到这个例外。
但是, 这就产生了一些额外的工作,因为我必须显式地设置HeaderItem装饰,并且还要在适配器中进行设置,在绑定标题项时,我必须注意内部Item及其所有逻辑,例如单击侦听器等。
如果能支持开箱即用的列表大小更改,我会很高兴。