ページングライブラリを使用して、サーバーから取得するアイテムのリストにページ番号を付けています。最初に、フラグメントがロードされると、空のリストが返されます。しかし、フラグメントを変更してそのフラグメントに戻ると、ロードされたリストが表示されます。デバッグ後、データが実際にフェッチされているのを確認しましたが、空のリストがフラグメントに渡されました。
ItemDataSource:
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Item> callback) {
apiService.getItems(OFFSET)
.enqueue(new Callback<ItemWrapper>() {
@Override
public void onResponse(@NonNull Call<ItemWrapper> call,@NonNull Response<ItemWrapper> response) {
callback.onResult(response.body().getItems(), null, OFFSET + 25);
}
@Override
public void onFailure(@NonNull Call<ItemWrapper> call,@NonNull Throwable t) {
t.printStackTrace();
}
});
}
@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Item> callback) {
}
@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Item> callback) {
apiService.getItems(params.key)
.enqueue(new Callback<ItemWrapper>() {
@Override
public void onResponse(@NonNull Call<ItemWrapper> call,@NonNull Response<ItemWrapper> response) {
Integer key = response.body().getItems().isEmpty() ? null : params.key + 25;
callback.onResult(response.body().getItems(), key);
}
@Override
public void onFailure(@NonNull Call<ItemWrapper> call,@NonNull Throwable t) {
t.printStackTrace();
}
});
}
ItemDataSourceFactory:
@Override
public DataSource create() {
ItemDataSource itemDataSource = new ItemDataSource();
itemLiveDataSource.postValue(itemDataSource);
return itemDataSource;
}
public MutableLiveData<ItemDataSource> getItemLiveDataSource() {
return itemLiveDataSource;
}
ItemViewModel:
private LiveData<ItemDataSource> liveDataSource;
private LiveData<PagedList<Item>> itemPagedList;
private ItemViewModel(Application application) {
ItemDataSourceFactory factory = new ItemDataSourceFactory();
liveDataSource = factory.getItemLiveDataSource();
PagedList.Config config = (new PagedList.Config.Builder())
.setEnablePlaceholders(false)
.setPageSize(ItemDataSource.LIMIT).build();
itemPagedList = (new LivePagedListBuilder(factory, config)).build();
}
public LiveData<PagedList<Item>> getItems() {
return itemPagedList;
}
フラグメント:
ItemViewModel itemViewModel = ViewModelProviders.of(this).get(ItemViewModel.class);
itemViewModel.getItems.observe(this, items -> {
adapter.submitList(items);
})
100%確実ではありませんが、これは非同期リクエストを実行しているためだと思います。 loadInitial()
のように同期的に実行するように変更してみてくださいrequest.execute()
私もこの問題を一度経験しましたが、一部のフラグメントで機能しない理由を理解できません。私が見つけた解決策は、aldoはより速いスケッチのようなもので、フラグメントを2回ロードすることです。
ヤシン・アジディは正しいです。 loadinitial()
は、PagedListが作成された同じスレッドですぐに呼び出します。 APIが非同期であるため、メソッドは初めて空で実行されます
私のように、誰かがloadInitial
で非同期のRxJava/Kotlin呼び出しを使用している場合。何時間も苦労してやっと解決策を見つけました。
Observer
メソッドで遅延ハンドラー(500ミリ秒)を使用してみましたが、気まぐれで、すべてのシナリオで機能しませんでした。 setFetcher
とRx observeOn
を使用してどれだけ同期させようとしても、一貫して機能しません。
私の解決策は.blockingSubscribe
私のObservable内。私のデータフェッチャーは、独自の同時実行性が範囲外のSocketライブラリを使用していたため、ページングが必要とするようにプロセスを完全に同期できるとは保証できませんでした。 (より良いドキュメントIMOを必要とするプロセス)。とにかく、これが私の解決策です、うまくいけばそれは同じ問題を持つ他の人を助ける:
override fun loadInitial(
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, ResultItem>
) {
mySocketClientRxRequest()
.subscribe ({
callback.onResult(it.resultItems 1, 2)
},{
it.printStackTrace()
})
}
に
override fun loadInitial(
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, ResultItem>
) {
mySocketClientRxRequest()
.blockingSubscribe ({
callback.onResult(it.resultItems 1, 2)
},{
it.printStackTrace()
})
}