1

I using the Paging library in my project.

In Activity, an observer observes the data that the Room library return, when the Room's data changes, the UI update.

And when I scroll to the end of the RecyclerView, the Paging library starts to load data into Room.

But the RecyclerView's list refreshes incorrectly and scroll to the previous position.

What's wrong with my code?

enter image description here Activity(oberser).

PagingItemRepository repository = new PagingItemRepository(FindDatabase.getInstance(PagingListActivity.this).pagingItemDao());

        repository.getAllItems().observe(this, new Observer<PagedList<ItemEntity>>() {
            @Override
            public void onChanged(PagedList<ItemEntity> itemEntities) {
                adapter.submitList(itemEntities);
            }
        });

Adapter

class PagingListAdapter extends PagedListAdapter<ItemEntity, ItemHolder> {

        protected PagingListAdapter() {
            super(DIFF_CALLBACK);
        }

        protected PagingListAdapter(@NonNull DiffUtil.ItemCallback<ItemEntity> diffCallback) {
            super(diffCallback);
        }

        @NonNull
        @Override
        public ItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            return new ItemHolder(LayoutInflater.from(PagingListActivity.this).inflate(R.layout.list_item, parent, false));
        }

        @Override
        public void onBindViewHolder(@NonNull ItemHolder holder, int position) {
            ItemEntity entity = getItem(position);
            if (entity != null) {
                String value = entity.getText();
                holder.textView.setText(value);
            }
        }

    }

    class ItemHolder extends RecyclerView.ViewHolder {

        TextView textView;

        public ItemHolder(@NonNull View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.text);
        }
    }

DiffUtil

private static DiffUtil.ItemCallback<ItemEntity> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<ItemEntity>() {
                // Concert details may have changed if reloaded from the database,
                // but ID is fixed.
                @Override
                public boolean areItemsTheSame(ItemEntity oldEntity, ItemEntity newEntity) {
                    return oldEntity.getId() == newEntity.getId();
                }

                @Override
                public boolean areContentsTheSame(ItemEntity oldEntity,
                                                  ItemEntity newEntity) {
                    return oldEntity.equals(newEntity);
                }
            };

PagingItemRepository

public class PagingItemRepository {
    private PagingItemDao itemDao;
    LivePagedListBuilder<Integer, ItemEntity> builder;

    public PagingItemRepository(PagingItemDao itemDao) {
        this.itemDao = itemDao;
        DataSource.Factory<Integer, ItemEntity> factory = itemDao.getAllItems();
        PagedList.Config config = new PagedList.Config.Builder().
                setPageSize(60).
                setPrefetchDistance(0).
                setEnablePlaceholders(true).
                setInitialLoadSizeHint(120).
                //setMaxSize(200).
                build();
        builder = new LivePagedListBuilder<>(factory, config);
        builder.setBoundaryCallback(new MyBoundaryCallback(itemDao));
    }

    LiveData<PagedList<ItemEntity>> getAllItems() {
        return builder.build();
    }
}

MyBoundaryCallback

public static class MyBoundaryCallback extends PagedList.BoundaryCallback<ItemEntity> {
        private PagingItemDao itemDao;

        public MyBoundaryCallback(PagingItemDao itemDao) {
            this.itemDao = itemDao;
        }

        @Override
        public void onZeroItemsLoaded() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final List<ItemEntity> entities = new ArrayList<>();
                    for (int i = 0; i < 30; i++) {
                        count++;
                        ItemEntity entity = new ItemEntity();
                        entity.setText(count + "");
                        entities.add(entity);
                    }
                    itemDao.addItems(entities);
                }
            }).start();
        }

        @Override
        public void onItemAtFrontLoaded(@NonNull ItemEntity itemAtFront) {
        }

        @Override
        public void onItemAtEndLoaded(@NonNull ItemEntity itemAtEnd) {
            final Long id = itemAtEnd.getId();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (id >= 530) {
                        return;
                    }

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    final List<ItemEntity> entities = new ArrayList<>();
                    for (int i = 0; i < 50; i++) {
                        count++;
                        ItemEntity entity = new ItemEntity();
                        entity.setText(count + "");
                        entities.add(entity);
                    }


                    itemDao.addItems(entities);
                }
            }).start();
        }
    }

PagingItemDao

@Dao
public interface PagingItemDao {

    @Query("select * from item")
    DataSource.Factory<Integer, ItemEntity> getAllItems();

    @Insert
    void addItems(List<ItemEntity> entities);

    @Query("delete from item")
    void delete();
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
and1990
  • 55
  • 1
  • 9

1 Answers1

0

Finally, I solved this problem. ItemEntity, which is my Room entity, its id type is Long type(Reference type) before, then I changed the Long to long type(Basic type), then everything is fine.

and1990
  • 55
  • 1
  • 9