我希望在我的应用程序中使用新的体系结构组件“分页库” https://developer.android.com/topic/libraries/architecture/paging.html,该组件从服务器中获取数据并在recyclerview中显示。
分页库是一个很好的补充,有助于管理内容分页。我检查了所有样本,它们工作正常。但是我有一个要求,那就是当我们滚动到recyclerview的末尾并且下一页开始加载时(由分页库管理),我需要在底部显示一个进度条行。
我知道如何使用recyclerview滚动侦听器和2种视图类型执行此操作。但是我正在寻找的解决方案是如何使用“分页库”来做到这一点。它具有启用占位符的选项,这不是我想要的。
对此,我们将给予任何帮助。
android android-architecture-lifecycle android-architecture-components android-paging
我已经编写了这个简单的示例来测试分页库并使用LiveData观察对PagedList的更改,但是在LiveData<PagedList<Integer>>创建对象时它仅通知一次观察者。我在活动中使用按钮加载了更多数据,并且pagedList对象已正确加载,但未观察到更改。这是我的活动代码:
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
Button b = findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PagedList<Integer> s = mainViewModel.getIntegers().getValue();
s.loadAround(s.size());
}
});
mainViewModel.setUpPaging(1);
mainViewModel.getIntegers().observe(this, new Observer<PagedList<Integer>>() {
@Override
public void onChanged(@Nullable PagedList<Integer> integers) {
//logging some text
Log.i("MyLog","new list Observed"); …Run Code Online (Sandbox Code Playgroud) 我已经在我的应用程序中集成了分页组件,它的工作非常好(几乎).我有数据库+网络模型.数据库最初有一些消耗的项目LivePagedListBuilder.我观察到这一点LiveData<PagedList<InboxEntity>>并最终将列表提供给PagedListAdapter#submitList(PagedList<T> pagedList),例如:
LiveData<PagedList<Entity>> entities;
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder()).setEnablePlaceholders(true)
.setPrefetchDistance(5)
.setEnablePlaceholders(false)
.setPageSize(10)
.setInitialLoadSizeHint(10)
.build();
entities = new LivePagedListBuilder<>(DAO.getItemList(), pagedListConfig)
entities.observe(this, new Observer<PagedList<Entity>>() {
@Override
public void onChanged(@Nullable PagedList<Entity> inboxEntities) {
inboxAdapter.submitList(inboxEntities);
isFirstLoad = false;
}
});
Run Code Online (Sandbox Code Playgroud)
DAO#getItemList回报DataSource.Factory<Integer, Entity>.
我正在侦听边界回调并在到达分页列表末尾时触发网络呼叫.该调用再次填充数据库.
还有一件事.我已AdapterDataObserver在循环器视图上注册,因为如果在开头插入了一个项目,我将滚动到顶部位置:
RecyclerView.AdapterDataObserver adapterDataObserver = new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
if (positionStart == 0) {
layoutManager.scrollToPositionWithOffset(positionStart, 0);
}
}
};
Run Code Online (Sandbox Code Playgroud)
我在这个模型中面临一个问题:
进行网络调用后,再次填充数据库并onChanged …
android android-recyclerview android-architecture-components android-jetpack android-paging
我正在使用分页库和房间,使我的房间数据库成为我的应用程序的单层真相。当使用改造从服务器获取数据时,我将结果本地保存在db中,然后使用分页库从db中获取数据。我正在使用BoundaryCallback。
@Override
public void onZeroItemsLoaded() {
requestAndSaveData();
}
@Override
public void onItemAtEndLoaded(@NonNull Photo itemAtEnd) {
requestAndSaveData();
}
Run Code Online (Sandbox Code Playgroud)
private void requestAndSaveData() {
if (isRequestInProgress) return;
isRequestInProgress = true;
apiInterface.getPhotos(lastRequestPage, NETWORK_PAGE_SIZE).enqueue(new Callback<PhotoList>() {
@Override
public void onResponse(Call<PhotoList> call, Response<PhotoList> response) {
if (response.isSuccessful()) {
cache.insertPhotos(response.body().getHits()); //todo only save 20 - 40 items
lastRequestPage++;
isRequestInProgress = false;
Log.i("deb", "number from boundary: " + response.body().getHits().size());
}
}
Run Code Online (Sandbox Code Playgroud)
当数据库中没有项目或用户滚动到最后一个项目时,我调用requestAndSaveData()从服务器获取数据并将其保存到数据库中的方法。
我的问题是,从服务器加载下一页并将其保存到数据库时,如何在列表底部显示进度条,这可能需要很长时间?
我正在使用Paging库直接从网络加载日期.我是否必须实现逻辑来停止获取数据?在我的情况下,可以是当收到的项目数低于页面大小时.目前,当我到达列表末尾时,lib会不断加载新页面.
pagination android android-architecture-components android-paging
我正在尝试将页面库与新版本一起使用。我正在使用凌空从网络上获取我的数据。每当我从网络获取数据时,都会获取数据,但是当调用转到观察者时,显示的列表大小为零。我不确定自己在做什么错。
我是android新手,所以对分页知之甚少。自从我尝试以来已经过去了几天,但仍然无法弄清楚。
我的gradle如下
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.athansys.mypagingapplication"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.volley:volley:1.1.0'
implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "android.arch.paging:runtime:1.0.1"
implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
Run Code Online (Sandbox Code Playgroud)
}
我的MainActivity看起来像:
package com.example.athansys.mypagingapplication;
import android.arch.lifecycle.Observer; …Run Code Online (Sandbox Code Playgroud) 我正在探索Architecture Components套件的Paging库。
我的问题是在使用Paging提供的结构时实现“加载更多”视图(旋转器)。
我通常会手动实现无限滚动模式。这意味着我通常会向适配器提供一个“视图模型”列表(在建筑组件意义上不一定是视图模型,只是代表所有列表项的实体),包括一个可选附加的“加载更多”对象,适配器随后将显示为“加载”视图。
该解决方案具有某些优势,例如更好的可测试性以及使UI层尽可能简单和被动,从而使适配器与任何业务逻辑分离。
分页似乎并不容易。从我所看到的,您应该将PagedList实例流连接到该PagedListAdapter.submitList方法,魔术本身就会发生。
然后,为了添加微调器,您实际上要从视图模型中公开“网络状态”,将其分别传递给适配器,然后让适配器动态注入微调器。
就是这样在示例代码中完成的-https: //github.com/googlesamples/android-architecture-components/blob/master/PagingWithNetworkSample/app/src/main/java/com/android/example/paging/pagingwithnetwork/reddit /ui/PostsAdapter.kt
class PostsAdapter /* snip */ {
private var networkState: NetworkState? = null
// snip
private fun hasExtraRow() = networkState != null && networkState != NetworkState.LOADED
// snip
override fun getItemCount(): Int {
return super.getItemCount() + if (hasExtraRow()) 1 else 0
}
fun setNetworkState(newNetworkState: NetworkState?) {
val previousState = this.networkState
val hadExtraRow = hasExtraRow()
this.networkState = newNetworkState
val hasExtraRow = hasExtraRow()
if (hadExtraRow …Run Code Online (Sandbox Code Playgroud) android recycler-adapter android-architecture-components android-paging
目前,我正在研究p2p messenger app.我们的消息存储在房间数据库中.当我们发送或接收新消息时,我们将其插入房间db.它的工作原理是触发了来自RecyclerView.AdapterDataObserver的方法onItemRangeInserted.
但是,当数据源丰富最后一页(从db获取最后一个数据)时,不会调用onItemRangeInserted方法.只有在第二次插入db后,才会触发此方法.
我们使用room和LivePagedListBuilder实现的默认PositionalDataSource.
那么,将它用于房间的实时分页是真的吗?如果是,那么可能是什么问题?
如果需要一些代码,请告诉我.因为有很多代码,我不确定应该附加哪个部分.
我有一个连续调用loadAfter的PageKeyedDataSource,并且所有项目都多次添加到Recyclerview中。从API方面来看,null lastEvaluatedKey表示给我第一页,这对于为什么它不断调用以获取第一页还是A是有意义的。如果没有更多数据要获取(又名params.key == null?和B ,则它不应该停止) t是COMPARATOR在适配器不允许添加相同的项目多次吗?我在想什么?
PageKeyedDataSource.kt
class ReservationsPageKeyedDataSource(private val retryExecutor: Executor) : PageKeyedDataSource<String, Reservation?>() {
private var retry: (() -> Any)? = null
val initialLoad = MutableLiveData<PagingNetworkState>()
fun retryAllFailed() {
val prevRetry = retry
retry = null
prevRetry?.let {
retryExecutor.execute {
it.invoke()
}
}
}
override fun loadInitial(
params: LoadInitialParams<String>,
callback: LoadInitialCallback<String, Reservation?>
) {
val request = Api.reservationsService.getReservations(dateType = RERVATIONS_DATE_TYPE.future, last = null)
initialLoad.postValue(PagingNetworkState.LOADING)
// triggered by a refresh, execute in sync
try …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它从 API获取158 个项目的列表,将其存储在 Room 中,然后将其显示给用户。RoomDB 是事实的来源。
这是我的 ViewModel 上从数据库获取结果的代码:
private val pagingConfig =
PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 300)
fun getList(filters: Filters): Flow<PagingData<Character>> {
return Pager(pagingConfig) {
repository.getCharacters(filters)
}.flow.map {
it.asDomainModel()
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的片段上填充适配器的代码:
private fun fetchData(filters: Filters) {
lifecycleScope.launch {
charactersViewModel.getList(filters).collectLatest { pagedList ->
characterAdapter.submitData(pagedList)
}
}
}
Run Code Online (Sandbox Code Playgroud)
当前行为:
我已经尝试过的:
由于我获取数据异步我使用这段代码从这个尝试的文章,以防止在加载数据时适配器是空的。但它没有用
characterAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
Run Code Online (Sandbox Code Playgroud)
我期望达到的目标:
能够滚动到列表底部并在不丢失滚动位置的情况下进行配置更改“无需随着列表变大而增加我的pageSize ”
android kotlin android-architecture-components android-paging android-paging-library
android-paging ×10
android ×9
android-architecture-components ×7
kotlin ×2
pagination ×2
android-architecture-lifecycle ×1
java ×1
pagedlist ×1
retrofit2 ×1
viewmodel ×1