3

I am using a android paging library to display a list of data in a fragment. It works, but when i rotate the screen, the list is loaded again instead of get already loaded data. I did it for this article. What is the problem?

This is my RxPagingSource

public Single<LoadResult<Integer, Book>> loadSingle(@NotNull LoadParams<Integer> loadParams) {
    Integer nextPageNumber = loadParams.getKey();
    if (nextPageNumber == null) {
        nextPageNumber = 1;
    }

    return dataApi.getBooksCatalog(nextPageNumber, new ArrayMap<>(), preferencesHelper.auth())
            .subscribeOn(Schedulers.io())
            .map(this::toLoadResult)
            .onErrorReturn(LoadResult.Error::new);
}

private LoadResult<Integer, Book> toLoadResult(ResponseData<DataList<Book>> response) {
    int currentPage = response.getData().getCurrentPage();
    return new LoadResult.Page<>(
            response.getData().getData(),
            currentPage > 1 ? currentPage - 1 : null,
            response.getData().getData().isEmpty() ? null : currentPage + 1);
}

public Integer getRefreshKey(@NotNull PagingState<Integer, Book> pagingState) {
    Integer anchorPosition = pagingState.getAnchorPosition();
    if (anchorPosition == null) {
        return null;
    }

    LoadResult.Page<Integer, Book> anchorPage = pagingState.closestPageToPosition(anchorPosition);
    if (anchorPage == null) {
        return null;
    }

    Integer prevKey = anchorPage.getPrevKey();
    if (prevKey != null) {
        return prevKey + 1;
    }

    Integer nextKey = anchorPage.getNextKey();
    if (nextKey != null) {
        return nextKey - 1;
    }

    return null;
}

I did not understand in which case the getRefreshKey() method should be called.

PagingDataAdapter<T, V> and DiffUtil.ItemCallback are standard...

In My ViewModel

@HiltViewModel
public class BooksViewModel extends BaseDisposablesViewModel {

    PagingConfig pagingConfig = new PagingConfig(50, 25, true, 100, 200);
    private final DataApiInterface dataApi;
    private final SharedPreferencesHelper preferencesHelper;
    Flowable<PagingData<Book>> flowable;


    @Inject
    BooksViewModel(DataApiInterface dataApi, SharedPreferencesHelper preferencesHelper) {
        this.dataApi = dataApi;
        this.preferencesHelper = preferencesHelper;
        init();
    }

    private void init() {
        CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(this);
        Pager<Integer, Book> pager = new Pager<>(
                pagingConfig,
                () -> new BooksPagingSource(dataApi, preferencesHelper)
        );

        flowable = PagingRx.getFlowable(pager);
        PagingRx.cachedIn(flowable, viewModelScope);
    }

}

And my Fragment...

@AndroidEntryPoint
public class BooksFragment extends BaseFragment {

    private FragmentBooksBinding binding;
    private final CompositeDisposable disposable = new CompositeDisposable();
    private BooksPagingAdapter pagingAdapter;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BooksViewModel viewModel = new ViewModelProvider(requireActivity()).get(BooksViewModel.class);

        pagingAdapter = new BooksPagingAdapter(new BooksPagingAdapter.BookComparator());
        disposable.add(viewModel.flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(bookPagingData -> pagingAdapter.submitData(getLifecycle(), bookPagingData)));
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentBooksBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        binding.list.setAdapter(pagingAdapter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        disposable.clear();
    }
}

0 Answers0