Список RecyclerView обновляется некорректно при использовании библиотеки подкачки

Я использую библиотеку подкачки в своем проекте.

В Activity наблюдатель наблюдает за данными, возвращаемыми библиотекой Room, при изменении данных Room обновляется пользовательский интерфейс.

И когда я прокручиваю до конца RecyclerView, библиотека Paging начинает загружать данные в Room.

Но список RecyclerView обновляется некорректно и прокручивается до предыдущей позиции.

Что не так с моим кодом?

введите описание изображения здесь Действия (наблюдатель).

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);
            }
        });

Адаптер

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();
}

person and1990    schedule 01.11.2019    source источник


Ответы (1)


Наконец-то я решил эту проблему. ItemEntity, который является моей сущностью Room, раньше его тип идентификатора был Long (ссылочный тип), затем я изменил тип Long на long (базовый тип), тогда все в порядке.

person and1990    schedule 04.11.2019