仅具有本地 Room 数据库的 Android Paging v3:如何滚动到分页列表中的特定位置?

Posted

技术标签:

【中文标题】仅具有本地 Room 数据库的 Android Paging v3:如何滚动到分页列表中的特定位置?【英文标题】:Android Paging v3 with just local Room database: how do I scroll to specific position in a paged list? 【发布时间】:2021-12-13 04:30:49 【问题描述】:

我不确定这是否是 Paging v3 的正确用例,但这里是这样。

我的所有数据都在本地 Room 数据库中(没有网络调用,没有 API)。我有一个潜在的大型待办事项列表数据集(每个日期一个)。我有一个 RecyclerView 向用户显示这些待办事项列表。显然,我不想为用户加载所有待办事项列表,所以我选择使用分页数据源并决定使用 Paging v3。

我关注this youtube tutorial 进行分页实现。

我已经为基本用例做好了一切工作,但现在我被卡住了。我想让用户跳转到列表中的特定日期。如果他们滚动到新日期并为他们创建新的待办事项列表,我也想听听。

我不确定如何将我的 RecyclerView 或分页源滚动到列表中的特定点。

我的道:

    @Transaction
    @Query("SELECT * FROM todo_list ORDER BY date DESC")
    fun loadTodoListsPaged(): PagingSource<Int, TodoList>

我的视图模型:

class TodoListViewModel(application: Application) : androidViewModel(application) 

    val todoListsPaged = Pager(PagingConfig(
            pageSize = 10,
            enablePlaceholders = false,
            maxSize = 30
    )) 
        myTodoListDao.loadTodoListsPaged()
    .flow.cachedIn(viewModelScope)

我的适配器:

class TodoListPagingDataAdapter(
    val context: Context
): PagingDataAdapter<TodoList, TodoListViewHolder>(TodoListDiffUtilCallback()) 

...


我不确定这是否可能,因为Room only supports PagingSource with Key of type Int.

使用Paging v3,如何跳转或滚动到列表中的特定点?

理想情况下,我只需传递一些日期,它就会告诉我我需要的页面。然后我将页面传递给适配器/recyclerview/pager,它会为我加载它。

更新

我刚刚将一个可变日期列表存储为 LiveData,并使用转换开关映射将其映射到我的待办事项列表(将日期列表传递到数据库并返回相关列表)。当用户滚动时,我从这个可变列表中添加/删除日期,它会自动更新。它比分页好得多,而且更简单。如果有人想了解更多详情,请询问。

【问题讨论】:

【参考方案1】:

不知道有没有办法根据适配数据中的特定值进行跳转。 如果发布的答案表明您拥有更多权力。

如果您找不到使用 PagingSource,我想我可能有一个解决方案。

当用户以编程方式输入日期时,滚动列表直到找到它。

fun scrollTilFindDate(date : Date, offset : Int)
    var dateFound : Boolean = false;
    var todos: List<Todo> = adapter.snapshot().items;
    for(todo : Todo in todos)
       if(todo.date == date)
          dateFound = true;
          break;
       
    
    if(!recyclerView.canScrollVertically(1) || dateFound)
        return;
    else
        var newOffset : Int = offset+pageSize;
        recyclerView.post(()->
              recyclerView.scrollToPosition(newOffset);
              scrollTilFindDate(date,newOffset);  
        );
    

 

【讨论】:

以上是关于仅具有本地 Room 数据库的 Android Paging v3:如何滚动到分页列表中的特定位置?的主要内容,如果未能解决你的问题,请参考以下文章

Android jetpack room 将外部数据库导入到本地数据库(附带创建Sqlite3的教程)

Android Room 使用案例

具有唯一替换约束的 Android Room 表

Android Room:使用 Room 插入关系实体

TypeConverter() 在 Android 中的 Room 出现 TypeConverter 错误时具有私有访问权限

Android Room迁移测试:主键位置的差异导致无根据的测试失败