分页库很棒.但我发现缺乏这个功能:
PageKeyedDataSource:loadInitial调用时顶部的视图,loadAfter调用时列表底部的视图.callback调用时视图应该消失.由于现在不可能,有没有人知道使用PagingLibrary的方法?至少在同一列表中使用不同视图的方法.
我有一个Android待办事项列表应用程序,使用Room访问SQLite数据库.然后我想在导航抽屉中列出可用列表.所以我使用了Paging Library.现在RecyclerView是空的,我不知道为什么.顺便说一句:我的名单都没有.我是初学者,所以我坚持官方教程.我已经发现,他们错了,ViewModel需要一个空的构造函数.现在的情况如下:设置适配器的方法成功调用(8),ViewModel创建(7)Adapter创建(1),setList()方法调用(9),但没有Holder创建(4),没有onCreateViewHolder或被onBindViewHolder调用(2,3),没有DiffCalback调用任何方法(5,6),只显示一个空的Recycler视图.该PagedList<SQLList>包含正确的信息,但没有信息被传递给适配器.有谁知道为什么?//对不起我的英语不好.
适配器类:
//this is my Adapter. SQLList is my object (Equivalent to the User object in
the tutorial)
public class ListsAdapter extends PagedListAdapter<SQLList,ListsAdapter.Holder> {
private Context context;
public ListsAdapter(Context context) {
//1
super(DIFF_CALLBACK);
this.context = context;
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
//2
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.list_item,null);
return new Holder(view);
}
@Override
public …Run Code Online (Sandbox Code Playgroud) 从移后SqliteOpenHelper到room我的应用程序中,我试图写的测试DAO类。
我的 DAO 看起来像这样:
@Query("SELECT * FROM cards")
fun getAllCards(): List<CardData>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCard(vararg cardData: CardData): List<Long>
@Query("SELECT * FROM cards ORDER BY isRead ASC, id DESC")
fun getItemList(): DataSource.Factory<Int, CardData>
@Query("SELECT * FROM cards where instr(title, :query) > 0 ORDER BY isRead ASC, id DESC")
fun getItemList(query: String): DataSource.Factory<Int, CardData>
@Query("UPDATE cards set isRead = 1 where title = :title")
fun markRead(title: String): Int
Run Code Online (Sandbox Code Playgroud)
在写测试getAllCards,insertCard并且markRead是微不足道的,我仍然不知道我怎么测试的API,其回报率 …
我正在尝试使用 paging 3 库对我的 REST API 进行分页,特别是使用该类RemoteMediator。
我想要实现的是,我的本地数据库用于 UI 的初始呈现,如果显示的数据有任何更改,它会通过休息调用进行反应式更新。
我现在的奇怪行为是,分页仅在第一次时按预期工作:当用户滚动 RecyclerView 时,页面会增量加载(意味着触发 REST 调用)。
在我的本地数据库中有数据后,在开始时只有一个休息调用(具有初始加载大小),在结束时会连续触发大约 4 个请求。因此,它不会像第一次那样增量请求我的 API,它只是在最后触发所有请求。
这种行为正常吗?或者这是一个错误?
我的远程中介代码:
@ExperimentalPagingApi
class PageableRemoteMediator<T : Any>(
private val pageKeyId: String,
private val apiRequestFun: suspend (PageKey?, Int) -> ApiResult<Page<T>>,
private val entityPersisterFun: suspend (Page<T>) -> Unit,
application: Application
) : RemoteMediator<Int, T>() {
private val db = DatabaseProvider.getDatabase(application)
private val pageKeyDao = db.pageKeyDao()
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(loadType: LoadType, state: PagingState<Int, …Run Code Online (Sandbox Code Playgroud) 我正在制作一个待办事项列表应用程序,我想拥有一个精美的列表,其中任务按日期分组在标题下(类似于Splen-DO的内容)。我将Android Paging库(与RecyclerView一起)与Room(作为数据存储)一起使用。对于标题,我使用RecyclerView的视图类型,并将标题添加到列表中,我使用的是自定义数据源,该数据包包装了Room的数据源,而不是返回Task Object,它返回的对象可以是Task或标头。
它是这样的:
一切正常,直到我对数据库进行更改。物品无缘无故地在RecyclerView中移动,有些重复并且在RecyclerView的乞求中有一些空的占位符。到目前为止,我一直在尝试解决“乞讨时出现空的占位符”问题。
我已经检查了我的数据源,它返回正确的数据且没有偏移量。然后我检查了适配器。getItem()方法返回所有具有偏移量的项,并在开头返回一些空项。当我开始深入研究时,我发现它是由PagedStorage中的某些mLoadingNullCount引起的,我不知道它的用途,因为它没有文档。
列表可正常
使用列表可正常
使用在我对列表进行更改之后,列表顶部的
空占位符空占位符
列表错误(gif)
错误列表
请忽略一些变量和类名,我使用一些捷克语单词,以便它们不会与某些系统类混淆。
Ukol =任务
适配器:
数据源:
片段:UkolListAdapter.javaMyDatasource.javaUkolListFragment.java
如果您需要更多代码或解释,请发表评论,我会为您添加。
我发现了一个错误。从房间数据库中的数据源可能不会给你名单staritng,你要求的,但在那里就是了,在loadInitial()并为您提供的索引(其中返回列表开始)中int position的parametr onResult()。因此,我在上返回了错误的数据loadInitial()。因此,我添加了一些算法,用于计算实际返回的数据LoadInitial()。我没有解决问题。
我想通过loadInitial或loadafter 中的callback.onError(或 callback.onRetryableError)将错误异常传递给我的分页适配器,但总是收到崩溃。经过一些调试后,我在库源中找到了这个:

这实际上是我在崩溃跟踪中收到的信息。只是“待办事项”。依赖版本:
'androidx.paging:paging-runtime-ktx:2.1.1'
在生产中出现这种异常消息是否可以,或者我做错了什么?无论如何......问题:任何其他“内置”方式将加载错误传递给适配器?
android android-architecture-components android-paging android-paging-library
我在我的项目中使用了 Jetpack 的Paging 3库来处理数据分页。我有一个用例,当用户更改搜索请求中的某些内容(例如添加/删除一些过滤器)时,我必须调用 API 并根据新的搜索请求使用新数据重新填充我的列表。但是当我创建新Pager实例并将其传递给我的PagingDataAdapter适配器时,它会抛出:
java.lang.IllegalStateException: Collecting from multiple PagingData concurrently is an illegal operation.
Run Code Online (Sandbox Code Playgroud)
我的实现是这样的:
存储库
class Repository {
fun getDataStream(request: Request): Flow<PagingData<Response>> {
return Pager(
config = PagingConfig(
pageSize = 10,
initialLoadSize = 10,
prefetchDistance = 3
),
initialKey = 1,
pagingSourceFactory = {
DataPagingSource(
request = request,
repository = this
)
}
).flow
}
fun getData(page: Int, request: Request): Result<Response> {
return remoteDataSource.getData(page, request)
}
}
Run Code Online (Sandbox Code Playgroud)
数据分页源
class DataPagingSource(
private …Run Code Online (Sandbox Code Playgroud) 在这个示例项目中,我有一个 DAO,它在 FTS4 表上使用 Paging 2 来搜索它,使用用户提供的搜索表达式:
@Query("SELECT snippet(paragraphsFts) FROM paragraphs JOIN paragraphsFts "+
"ON paragraphs.id == paragraphsFts.rowid WHERE paragraphsFts.prose "+
"MATCH :search ORDER BY sequence")
abstract fun filtered(search: String): DataSource.Factory<Int, String>
Run Code Online (Sandbox Code Playgroud)
我有一个BookRepositoryfiltered()函数,它只是通过对 DAO 的调用,我有一个SearchViewModel将 the 转换DataSource.Factory为 a的函数LiveData:
class SearchViewModel(search: String, repo: BookRepository) : ViewModel() {
val paragraphs = repo.filtered(search).toLiveData(pageSize = 15)
}
Run Code Online (Sandbox Code Playgroud)
vm.paragraphs.observe(this.viewLifecycleOwner) {
adapter.submitList(it)
}
Run Code Online (Sandbox Code Playgroud)
只要用户没有输入语法错误的搜索表达式,这就可以正常工作。在这种情况下,Room 会抛出异常,我看不到在哪里可以捕获它。
2020-08-30 …Run Code Online (Sandbox Code Playgroud) 按照此处提供的说明,我已经能够成功实现新的 alpha07 版本的 Paging 3 库:https : //developer.android.com/topic/libraries/architecture/paging/v3-paged-data#guava-livedata
但是,现在我需要检查返回的列表是否为空以便向用户显示视图或文本,但我无法在其分页设计的流结构中附加任何检查。
目前,这是我onViewCreated在遵循他们的指南后在 Java 中使用我的代码的方式:
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
Lifecycle lifecycle = lifecycleOwner.getLifecycle();
Pager<Integer, MyEntity> pager = new Pager<>(new PagingConfig(10), () -> viewModel.getMyPagingSource());
LiveData<PagingData<MyEntity>> pagingDataLiveData = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), lifecycle);
pagingDataLiveData.observe(lifecycleOwner, data -> adapter.submitData(lifecycle, data));
Run Code Online (Sandbox Code Playgroud)
我尝试.filter在我的datain上附加 a adapter.submitData(lifecycle, data),但null尽管列表为空,但它从未收到项目。
在这种情况下,如何检查提交给适配器的数据何时为空?我在他们的文档中找不到任何指针。
编辑:这是我找到的解决方案,在这里发布是因为所选的答案严格来说不是解决方案,也不是在 Java 中,而是引导我找到它的答案。
我有一个附加LoadStateListener我的转接器,监听时LoadType是REFRESH和LoadState的是NotLoading,再检查是否adapter.getItemCount是0。
LoadType对于这种情况,可能采用不同的方法更合适,但到目前为止,刷新对我来说是有效的,所以我选择了那个。
示例:
// …Run Code Online (Sandbox Code Playgroud) 我目前的问题是,LoadStateAdapter显示加载和错误状态的 my 不在 my 内居中recyclerview,它有一个 gridlayout 作为布局管理器。我在官方 android 开发者网站上没有找到任何关于此的信息,所以我在这里问:如何将我的LoadStateAdapter内部集中在我的 Recyclerview 中?
@AndroidEntryPoint
class ShopFragment : Fragment(R.layout.fragment_shop), ShopAdapter.OnItemClickListener {
private val shopViewModel: ShopViewModel by viewModels()
private val shopBinding: FragmentShopBinding by viewBinding()
@Inject lateinit var shopListAdapter: ShopAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bindObjects()
}
private fun bindObjects() {
shopBinding.adapter = shopListAdapter.withLoadStateFooter(ShopLoadAdapter(shopListAdapter::retry))
shopListAdapter.clickHandler(this)
}
override fun onDestroyView() {
requireView().findViewById<RecyclerView>(R.id.rv_shop).adapter = null
super.onDestroyView()
}
}
Run Code Online (Sandbox Code Playgroud)
@FragmentScoped
class ShopLoadAdapter(private val retry: () …Run Code Online (Sandbox Code Playgroud) android kotlin android-recyclerview android-paging android-paging-3
android ×10
android-paging ×10
android-room ×3
android-architecture-components ×2
java ×1
kotlin ×1