web-dev-qa-db-ja.com

ページングライブラリが最初に空のリストを返す

ページングライブラリを使用して、サーバーから取得するアイテムのリストにページ番号を付けています。最初に、フラグメントがロードされると、空のリストが返されます。しかし、フラグメントを変更してそのフラグメントに戻ると、ロードされたリストが表示されます。デバッグ後、データが実際にフェッチされているのを確認しましたが、空のリストがフラグメントに渡されました。

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);
})
16
Saurabh Thorat

100%確実ではありませんが、これは非同期リクエストを実行しているためだと思います。 loadInitial()のように同期的に実行するように変更してみてくださいrequest.execute()

8
Yassin Ajdi

私もこの問題を一度経験しましたが、一部のフラグメントで機能しない理由を理解できません。私が見つけた解決策は、aldoはより速いスケッチのようなもので、フラグメントを2回ロードすることです。

2
Edward Codarcea

ヤシン・アジディは正しいです。 loadinitial()は、PagedListが作成された同じスレッドですぐに呼び出します。 APIが非同期であるため、メソッドは初めて空で実行されます

1
Alexander L.

私のように、誰かが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()
                })
    }
0
Conti